У меня есть дочерний компонент в макете, которому я тоже хочу передать значение 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>
);
}
}
Спасибо за приведенный выше код React.cloneElement (child, {не меняется, он всегда остается прежним)
Можете ли вы поделиться Project code
Я только что добавил его выше или вы можете увидеть это здесь github.com/purencool/purencool_editor/blob/master/src/js/…
Итак, теперь я в файле ide/FileListing, почему вы делаете этот changeValue = (data) => (e) => {
Также я вижу, что вы забыли привязать функцию changeValue, измените ее, как это <span onClick = {this.changeValue.bind(this, dataObj.default_path)}>{dataObj.file_name}</span>
Он передает значение до props проекта, затем проецирует проходы до layout, и я хочу, чтобы layout передавал его дочернему ide. Возможно, это неправильный способ сделать это. Я новичок в реакции. =) Спасибо, что посмотрели.
Позвольте нам продолжить обсуждение в чате.
У вас есть пример реквизита
Ваш код работает, проверьте это codeandbox.io/s/ppr2k331jj, может быть некоторая проблема с тем, как вы обрабатываете данные или их рендеринг
@purencool, дайте мне знать, если код и ящик, который я связал, вам не помогает



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Думаю, ошибка в функции 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.
@NickProzee, исходный код действительно правильный. и это рекомендуемый способ
В фактическом коде нет ничего плохого, единственное, что я предполагаю, это то, что в компоненте <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
То, как вы передаете реквизиты дочерним компонентам, в
renderChildrenвыглядит хорошо. Ваш дочерний компонент должен иметь доступ кdataчерезthis.props.data. Пожалуйста, обратитесь к stackoverflow.com/questions/32370994/… о передаче реквизита детям. Не уверен, что ты имеешь в виду?