尽管在父级上调用了 setState,但 React 仍未渲染某些组件

React not rendering some components despite calling setState on parent

我正在尝试编写一个计算器类型的应用程序(即我给它一个输入列表,它对它们执行计算并显示结果),但是对于某些输入它不会更新当输入改变时输出。我的代码的相关部分:

class Results extends React.Component
{
    constructor (props)
    {
        super (props);
    }

    render ()
    {
        let entries = calculate (this.props);
        return  <div className="results">
                    {entries.map(e => <ResultRow key={e.code} code={e.code} name={e.name} />)}
                </div>;
    }
}
class CircuitRow extends React.Component
{
    constructor (props)
    {
        super (props);
        this.state = props.circuit;
        this.nameChange = this._nameChange.bind(this);
    }
    _nameChange (evt)
    {
        this.state.name = evt.target.value;
        this.setState (this.state);
        if (this.props.notifyChange) this.props.notifyChange (this.props.circuit);
    }
    render ()
    {
        return <tr>
            <td><input className="label" value={this.state.name} onChange={this.nameChange} /></td>
            (more fields deleted as not necessary to demonstrate issue)
        </tr>;
    }
}
class Form extends React.Component
{
    constructor(props) {
        super(props);
        this.state = {
            circuits: [ 
                { id: 1, name: "circuit 1", ... other fields ... },
                { id: 2, name: "circuit 2", ... },
                { id: 3, name: "circuit 3", ... } ],
            colours: "RBWK",
            nextRowId: 4
        };
        this.notifyCircuitChange = this._notifyCircuitChange.bind(this);
    }

    render ()
    {
        return  <div>
                  <form className='optionsForm'>
                    (working part of form for changing colours removed)
                    <table><tbody>
                      <tr><th>Circuit Name</th><th>Count</th></tr>
                      {this.state.circuits.map ((circuit, i) => 
                        <CircuitRow key={circuit.id} index={i} circuit={circuit} notifyChange={this.notifyCircuitChange} />)}
                    </tbody></table>
                  </form>
                  <Results colours={this.state.colours} circuits={this.state.circuits} />
                </div>;
    }

    _notifyCircuitChange (circuit) { this.setState(this.state); }

}


ReactDOM.render (<Form/>, document.getElementById('main'));

我没有显示 工作的部分表单,包括一组更改 Form.state.colours 字符串内容的复选框 -- 结果确实如此当我更改这些时成功更新,但是当我更改电路行之一的 'name' 字段时,新名称未显示在结果中 table,但旧名称保留在那里。

知道为什么没有更新吗?

在您的代码中,您将 nameField 的值存储为 CircuitRow 组件的状态,每次发生更改时,您都会在两个地方更新相同的内容:CircuitRow 的状态和父级的状态形式。相反,我建议您将 nameField 的值作为道具传递给 CircuitRow 组件并显示,每次有更改时,您应该触发一个回调函数,该函数在父状态中发生相同的更改。

您的电路数组最初看起来像这样:

[ 
  { id: 1, name: "circuit 1", value: "", ... other fields ... },
  { id: 2, name: "circuit 2", value: "", ... },
  { id: 3, name: "circuit 3", value: "", ... } ]

将值作为道具传递给每个 CircuitRow 组件,并在渲染中显示它。 更改时,从 CircuitRow 触发 notifyChange,更新 Form 组件中的值。

我认为问题出在这个函数中,你从 CircuitRow 组件传递道具值,就像你从 parent 收到的任何东西一样,你从 [=24= 传递相同的值],试试这个:

_nameChange (evt)
{
        let circuit = this.state.circuit;
        circuit.name = evt.target.value;
        this.setState({circuit});
        if (this.props.notifyChange) 
            this.props.notifyChange(circuit);
}

还有一件事,您需要将 id 传回 parent Form 以更改此函数中 parent 中指定的元素,因为在 Form 组件中你有一个数组 od circuits 并且你必须只更新特定的元素。像这样:

_nameChange (evt)
{
        let circuit = this.state.circuit;
        circuit.name = evt.target.value;
        this.setState({circuit});
        if (this.props.notifyChange) 
            this.props.notifyChange(circuit, this.props.key);
}

并且在 _notifyCircuitChange 方法中:

_notifyCircuitChange (circuit, id) 
{
    let circuits = this.state.circuits;
    for(let i in circuits){
        if(circuits[i].id == id){
            circuits[i] = circuit;
            break;
        }
    }
    this.setState({circuits});
}