0

Supposing I have this parent component.

Parent.jsx

render() { const headers = ["id","desc1", "desc2", "actions"]; return( <div> <input type = "text" placeholder = "Product Brand" value={ this.state.desc }/> <input type = "text" placeholder = "Product Brand" value={ this.state.desc2 }/> <button type = "button" onClick = { this.handleSubmit.bind(this) }>Add</button> <CustomTable mystate = { this.state } header = { headers } data = { this.props.store.productbrandlist }/> </div> ) } 

and this CustomTable.jsx

renderHeaders(){ return( this.props.header.map(function(header, index){ return <th key={index}>{header}</th> }) ) } renderRows(){ // console.log("here1"); // return( // <ListItem datarows = { this.props.data }/> // ) return this.props.data.map((list, id) => <ListItem mystate = {this.props.mystate} key_id={id} key={id} col = {list}/> ) } render(){ return( <table className="table"> <thead> <tr>{ this.renderHeaders() }</tr> </thead> <tbody> { this.renderRows() } </tbody> </table> ) } 

and this component which render the rows of the table

render(){ return( <tr key = { this.props.key_id }> { this.renderColumns() } { this.renderActions() } </tr> ) } renderColumns(){ var columns = [] for (var key in this.props.col) { if (this.state.isEditing){ columns.push(<td key = {key.id}><input ref = "txt" type = "text" value = { this.state.itemValue } onChange = { this.onTextChange.bind(this) } /></td>) } else { columns.push(<td key = {key.id}>{ this.props.col[key] }</td>) // this.setState({ // itemValue: key, // isEditing: false // }) } } return columns } renderActions(){ if (this.state.isEditing){ return ( <td> <button type="button" onClick = { this.handleSaveClick.bind(this) }>Save</button> <button type="button" onClick = { this.handlCancelClick.bind(this) }>Cancel</button> </td> ) } return( <td> <button type="button" onClick = { this.handleEditClick.bind(this) }>Edit</button> <button type="button" onClick = { this.handleDeleteClick.bind(this) }>Delete</button> </td> ) } 

My question is how do I configure it in such a way that when I click on the button edit which is created in the ListItem Component. The data will be displayed in the inputbox which is created in the parent.jsx

3
  • Write a function that changes the state in the parent component. Then pass this function to the child component as a props. Make a call to this function when you need to change the state of the parent. Using redux will be easier if the child component is deeply nested. Commented Apr 7, 2017 at 2:59
  • @cdaiga Sir, can you atleast give me a simple example using redux? thanks in advance. Js Bin will do. Thanks Commented Apr 7, 2017 at 3:03
  • see A cartoon intro to redux and Step by Step Guide To Building React Redux Apps on medium. I will advise you do that when you have some time. Commented Apr 7, 2017 at 3:15

1 Answer 1

1

Looking at your code, you just simply need to pass a reference to a parent method to the desired child, through props. I don't have your full code, so this is not tested, but should give you an idea on how to do it.

If there was another child layer between your parent and the ListItem, I would definitely encourage using Redux. Personally I'm ok with passing references two levels deep using props for simple projects.

To get your ListItem values to show up in the parent input fields, make the following changes:

In your Parent:

// you need two-way data binding between state and input values onChange(){ this.setState({ desc: this.refs.desc1.value, desc2: this.refs.desc2.value }); } // this method will get triggered by ListItem's edit button onClick onRowEdit(desc1, desc2){ this.setState({ desc: desc1, desc2: desc2 }); } render() { const headers = ["id","desc1", "desc2", "actions"]; return( <div> <input ref="desc1" type = "text" placeholder = "Product Brand" value={ this.state.desc } onChange={this.onChange.bind(this)} /> <input ref="desc2" type = "text" placeholder = "Product Brand" value={ this.state.desc2 } onChange={this.onChange.bind(this)/> <button type = "button" onClick = { this.handleSubmit.bind(this) }>Add</button> <CustomTable onEdit={ this.onRowEdit } mystate = { this.state } header = { headers } data = { this.props.store.productbrandlist }/> </div> ) } 

Your custom table renderRows:

renderRows(){ // console.log("here1"); // return( // <ListItem datarows = { this.props.data }/> // ) return this.props.data.map((list, id) => <ListItem onEdit={this.props.onEdit} mystate = {this.props.mystate} key_id={id} key={id} col = {list}/> ) } 

Finally in your ListItem inside handleEditClick method call the function passed in the props:

handleEditClick(){ // const desc1 = ... // const desc2 = ... this.props.onEdit(desc1, desc2); // this call will cause desc1, desc2 values to show up in the parent's input fields. } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot. Now, Im getting this.setState is not a function.
My bad, forgot to bind the function. Solved it now. Thanks a lot!
@sisnared I have a question, How should I implement redux or mobx in this? I have parent.jsx, table which is child of parent and rows.jsx which renders the rows of the table.
Redux can be used even for the simplest of React projects. But it's real value is noticed in bigger ones. The "how should I" part will come to you naturally, after you gain some familiarity with the way Redux works. I recommend trying out a couple of simple redux tutorials online. That should get you going.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.