I have a child component in a Layout that I want to pass a props value too. But I don't know how. In the class below the layoutFileDataRequest() receives a string variable from a child component on a click event. There is a need to send that value to one of the this.props.children components so it can update.
How do I do this? In the code below React.cloneElement(child, {
does not change it always stays the same which means I can't update the child prop.
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.log(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> ); } }
2 Answers
Answers 1
I think the error is in the renderChildren function.
Code
renderChildren() { return React.Children.map(this.props.children, child => { console.log(this.state.returnData); return React.cloneElement(child, { data: this.state.returnData }) }); }
New Code
renderChildren(){ return this.props.children.map(child => React.cloneElement(child, { data: {...this.state.returnData } }) ); }
Answers 2
There's nothing wrong with the actual code, the only thing that i am guessing is happening is that in the <FileListing />
component there is not and invocation to the prop (method) projectFileDataRequest
passing the update that wants to be transfer it to the <Layout />
's children.
TL;DR... Here is your code working and updating the <Layout />
's children just after receiving a click event in <FileListing />
.
https://codesandbox.io/s/5050w0p9kx
I hope it helps you
0 comments:
Post a Comment