如何在React中将道具从孩子传递给父母?

时间:2019-11-22 20:06:09

标签: javascript reactjs

我有一个动态表,该表呈现用户选择的项目列表。用户可以从下拉菜单中选择一个项目,然后将该项目添加到列表中。截至目前,我将项目列表存储在组件的状态下,这使表格可以动态呈现。我希望用户能够单击表中的某个项目,并能够编辑该项目的某些部分,例如他们选择的数量。用户单击表中的该项目后,将出现一个模态,其中填充了该特定项目的信息。我的问题是,在模态中,当用户更改说出该项目的数量时,我希望模态关闭,然后使用用户更改的值更新表。

是否可以将更新后的项目列表传递回父级?还是这不可行?如果是这样,那么解决这个问题的正确方法是什么?我将在下面发布我的代码,以便您可以更好地了解我要完成的工作。

注意,我的模态还不完整,但我只想知道如何将道具传递回父组件。

Parent.js


export default Parent extends React.Component{
 constructor(props){
  super(props);
   this.state = {
    ItemList = [],
    IDClicked = "",
   }

AddItemHandler(){
...stuff to add to ItemList

}

RenderModal(){
 let itemList = this.state.ItemList

 <ItemModal items={itemList} />
}

RowClick(e){
        //console.log(e.target.id)
        var items = this.state.ItemList;

        for(let i = 0; i < items.length; i++){
            if(items[i].ID == e.target.id){
                var Item = {
                    ID: items[i].ID,
                    PartName: items[i].PartName,
                    Quantity: items[i].Quantity   
                }
            }
        }
        //console.log("Item clicked: " + JSON.stringify(Item));
        this.setState({IDClicked: e.target.id})
        (document.getElementById('myModal')).style.display = "block";
    }

RenderTable(items){
        var rows = [];

        for(let i = 0; i < items.length; i++){
                    rows.push(
                        <tr style={{backgroundColor: '#B7BCDF'}} id={items[i].ID} key={i}>
                            <td style={{maxWidth: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}} onClick={this.RowClick.bind(this)} id={items[i].ID}>
                                {items[i].PartName}
                            </td>

                            <td  style={{maxWidth: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}} onClick={this.RowClick.bind(this)} id={items[i].ID}>
                                {items[i].Description}
                            </td>

                            <td  style={{maxWidth: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}} onClick={this.RowClick.bind(this)} id={items[i].ID}>
                                {items[i].Type}
                            </td>

                            <td  style={{maxWidth: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}} onClick={this.RowClick.bind(this)} id={items[i].ID}>
                                {items[i].Quantity}
                            </td>

                            <td  style={{maxWidth: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}} onClick={this.RowClick.bind(this)} id={items[i].ID}>
                                {items[i].Units}
                            </td>
                        </tr>
                    )      
        }
        return (

            <div className="TableScroll2" style={{width: '99.5%', height: 'none'}}>
                <table className="TableRows">
                    <tbody>
                        {rows}
                    </tbody>
                </table>
            </div>

        );
    }

render(){
 return(
   <div id="mymodal">
    this.RenderModal();
   </div>

   <div style={{width: '50%', marginLeft: 'auto', marginRight: 'auto'}}>
                    <div className="ParTableContainer" style={{marginTop: '5%'}}>
                        <table className="PartTableHeaderContainer" style={{textAlign: 'center'}}>
                            <thead>
                                <tr>
                                    <th style={{width: '20%'}}>Part Name</th>
                                    <th style={{width: '20%'}}>Description</th>
                                    <th style={{width: '20%'}}>Type</th>
                                    <th style={{width: '20%'}}>QTY</th>
                                    <th style={{width: '20%'}}>U/M</th>
                                </tr>
                            </thead>
                        </table>
                    </div>

                    {this.RenderTable(this.state.ItemList)}
                </div>
  <button style={{marginTop: '2%', marginBottom: '5%'}} onClick={this.AddItemHandler.bind(this)}>Add Item</button>
 }
}

1 个答案:

答案 0 :(得分:1)

您不能将道具从孩子传递给父母。但是,孩子可以通过多种方式与父母沟通,这可以用来解决您的问题。

通常的方法是使用回调-将函数从您的父母传递给孩子,孩子可以调用该函数来更新父母的状态。这是一个更新父状态的示例:

function Parent() {
    const [counter, setCounter] = useState(0)
    return (
        <div>
            Current: {state}
            <Child increment={() => {
                setCounter(current => current + 1)
            }}}/>
        </div>
    )
}

function Child(props) {
    return <button onClick={props.increment}>Click me</button>
}

(此示例使用钩子完成,我强烈建议学习)

这里没有挂钩:

class Parent extends Component {
    constructor() {
        this.state = { counter: 0 }
    }
    render() {
        return (
            <Child increment={() => {
                this.setState((current) => {
                    return { counter: current.counter + 1 }
                })
            }}}/>
        )
    }
}

function Child(props) {
    return <button onClick={props.increment}>Click me</button>
}