Передача значения дочернему компоненту (this.props.children) в React

У меня есть дочерний компонент в макете, которому я тоже хочу передать значение props. Но я не знаю как. В классе ниже layoutFileDataRequest () получает строковую переменную от дочернего компонента при событии щелчка. Это значение необходимо отправить в один из компонентов this.props.children, чтобы он мог обновиться.

Как мне это сделать? В приведенном ниже коде React.cloneElement(child, { не меняется, он всегда остается неизменным, что означает, что я не могу обновить дочернюю опору.

  export default class Layout extends React.Component {
    constructor(props) {
      super(props)

      this.layoutFileDataRequest = this.layoutFileDataRequest.bind(this);
      this.state = {
        newData: '',
        returnData: 'test',

      }
    }

    /**
     *  Received request from server add it to 
     *  react component so that it can be rendered
     */
    layoutFileDataRequest(data) {
      this.setState({ returnData:data })
    }


    renderChildren() {
      return React.Children.map(this.props.children, child => {
        console.info(this.state.returnData); 
          return React.cloneElement(child, {
            data: this.state.returnData
          })
      });
    } 

    /**
     *  Render request
     * 
     * 
     */
    render() {
      const { location } = this.props;
      const title = this.state.newData;
      return (
        <div id = "app-container" class = {title}>
          <Nav location = {location} />
          <main id = "main">
            <h1>{title}</h1>
            <section>
                {this.renderChildren()}
            </section>
          </main>
          <Project layoutFileDataRequest = {this.layoutFileDataRequest} />
          <Footer />
        </div>
      );
    }
  }


export default class Project extends React.Component {
  constructor(props) {
    super(props)

    this.projectFileDataRequest = this.projectFileDataRequest.bind(this);

    this.state = {
      newData: [],
    }

  }


  /**
   *  Received request from server add it to 
   *  react component so that it can be rendered
   */
  projectFileDataRequest(data) {
    this.props.layoutFileDataRequest(data);
  }


  /**
   *  Received request from server add it to 
   *  react component so that it can be rendered
   */
  componentDidMount() {
    ApiCalls.readSassDirData()
      .then(function (serverData) {
        this.setState({ newData: serverData[0].data })
      }.bind(this));
  }


  /**
   *  Render request
   */
  render() {
    const listOfObjects = this.state.newData;
    return (
      <aside id = "project">
        <h2>Files</h2>
        <FileListing listOfObjects = {listOfObjects} projectFileDataRequest = {this.projectFileDataRequest} />,
       </aside>
    );
  }
}

То, как вы передаете реквизиты дочерним компонентам, в renderChildren выглядит хорошо. Ваш дочерний компонент должен иметь доступ к data через this.props.data. Пожалуйста, обратитесь к stackoverflow.com/questions/32370994/… о передаче реквизита детям. Не уверен, что ты имеешь в виду?

Kevin Li 28.04.2018 07:19

Спасибо за приведенный выше код React.cloneElement (child, {не меняется, он всегда остается прежним)

purencool 28.04.2018 07:51

Можете ли вы поделиться Project code

Shrroy 28.04.2018 08:18

Я только что добавил его выше или вы можете увидеть это здесь github.com/purencool/purencool_editor/blob/master/src/js/…

purencool 28.04.2018 08:26

Итак, теперь я в файле ide/FileListing, почему вы делаете этот changeValue = (data) => (e) => {

Shrroy 28.04.2018 08:37

Также я вижу, что вы забыли привязать функцию changeValue, измените ее, как это <span onClick = {this.changeValue.bind(this, dataObj.default_path)}>{dataObj.file_name}</span>

Shrroy 28.04.2018 08:39

Он передает значение до props проекта, затем проецирует проходы до layout, и я хочу, чтобы layout передавал его дочернему ide. Возможно, это неправильный способ сделать это. Я новичок в реакции. =) Спасибо, что посмотрели.

purencool 28.04.2018 08:40

Позвольте нам продолжить обсуждение в чате.

Shrroy 28.04.2018 08:41

У вас есть пример реквизита

Nick Prozee 01.05.2018 12:08

Ваш код работает, проверьте это codeandbox.io/s/ppr2k331jj, может быть некоторая проблема с тем, как вы обрабатываете данные или их рендеринг

Shubham Khatri 01.05.2018 20:26

@purencool, дайте мне знать, если код и ящик, который я связал, вам не помогает

Shubham Khatri 02.05.2018 08:09
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
11
3 941
3

Ответы 3

Думаю, ошибка в функции renderChildren.

Код

 renderChildren() {
      return React.Children.map(this.props.children, child => {
        console.info(this.state.returnData); 
          return React.cloneElement(child, {
            data: this.state.returnData
          })
      });
    }

Новый Код

renderChildren(){
    return this.props.children.map(child => 
        React.cloneElement(child, { 
            data: {...this.state.returnData }
        })
    );
}

Спасибо за ответ. Я добавил то, что вы предложили, и это ошибка в консоли браузера TypeError: this.props.children.map is not a function.

purencool 02.05.2018 00:14

@NickProzee, исходный код действительно правильный. и это рекомендуемый способ

Shubham Khatri 02.05.2018 08:09

В фактическом коде нет ничего плохого, единственное, что я предполагаю, это то, что в компоненте <FileListing /> нет и вызова опоры (метода) projectFileDataRequest, передающей обновление, которое хочет передать его дочерним элементам <Layout />.

TL; DR ... Вот ваш код, работающий и обновляющий дочерние элементы <Layout /> сразу после получения события щелчка в <FileListing />.

https://codesandbox.io/s/5050w0p9kx

Я надеюсь это поможет тебе

Ваш код действительно работает нормально. Это аргументы cloneElement:

React.cloneElement(
  element,
  [props],
  [...children]
)

Вы передаете данные в качестве свойств дочерним компонентам.

Проверьте это: stackblitz.com/edit/react-xhwmd3?file=Layout.js

Другие вопросы по теме