【问题标题】:React - Table with inputs that dynamically updates parent state. Logical issueReact - 带有动态更新父状态的输入的表。逻辑问题
【发布时间】:2019-03-17 10:41:55
【问题描述】:

我是 React 开发的新手,不幸的是,我仍然像 AngularJS 开发人员一样思考。我想使用子表组件更新应用程序状态数据。我开发了一个如下所示的基本解决方案,但我不确定我的解决方案是否有效。如果你建议我一些材料来学习 ReactJS 的基本哲学,那将是非常棒的。感谢您的任何建议。

class App extends React.Component {
    constructor(){
        super();
        this.state = {
            data:
                [
                    {
                        "id":1,
                        "name":"Foo",
                        "age":"20"
                    },
                    {
                        "id":2,
                        "name":"Bar",
                        "age":"30"
                    },
                    {
                        "id":3,
                        "name":"Baz",
                        "age":"40"
                    }
                ]
        }
        this.updateState = this.updateState.bind(this);
    }
    updateState(e){
        const cpy = this.state.data.slice();
        this.setState({data:cpy});
    }
  render() {
      return <div className="App">
          <div class="table-responsive">
              <table class="table table-hover">
                  <thead>
                    <th>Id</th>
                    <th>Name</th>
                    <th>Age</th>
                    <th>Updated Name</th>
                  </thead>
                  <tbody>
                  {
                      this.state.data.map((x,i) => <TableRow key={i} data={x} updateHandler={this.updateState}></TableRow>)
                  }
                  </tbody>
              </table>
          </div>
      </div>;
  }
}

class TableRow extends React.Component{
    constructor(){
        super();
        this.updateInput = this.updateInput.bind(this);
    }
    updateInput(e){
        this.props.data.name = e.target.value;
        this.props.updateHandler();
    }

    render(){
        return <tr>
            <td>{this.props.data.id}</td>
            <td>{this.props.data.name}</td>
            <td>{this.props.data.age}</td>
            <td><input type="text" value={this.props.data.name} onChange={this.updateInput} /></td>
        </tr>
    }
}

ReactDOM.render(
  <App/>,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

【问题讨论】:

    标签: reactjs components parent-child dynamically-generated


    【解决方案1】:

    我建议查看官方reactjs.org 网站的文档。

    至于你的代码,我认为你犯的主要错误是你在 TableRow 组件 updateInput 方法中改变了你的道具:

    this.props.data.name = e.target.value;
    

    这不是在 React 中处理变化数据的方式。我会建议这样的事情:

    import React, { Component } from "react";
    
    class App extends Component {
      state = {
        data: [
          {
            id: 1,
            name: "Foo",
            age: "20"
          },
          {
            id: 2,
            name: "Bar",
            age: "30"
          },
          {
            id: 3,
            name: "Baz",
            age: "40"
          }
        ]
      };
    
      handleNameUpdate = (id, name) => {
        const { data } = this.state;
        const newData = data.map(row => {
          if (row.id === id) {
            return {
              ...row,
              name
            };
          }
          return row;
        });
        this.setState({ data: newData });
      }
    
      render() {
        return (
          <div className="App">
            <div className="table-responsive">
              <table className="table table-hover">
                <thead>
                  <tr>
                    <th>Id</th>
                    <th>Name</th>
                    <th>Age</th>
                    <th>Updated Name</th>
                  </tr>
                </thead>
                <tbody>
                  {this.state.data.map(row => (
                    <TableRow
                      key={row.id}
                      data={row}
                      onNameUpdate={this.handleNameUpdate}
                    />
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        );
      }
    }
    
    class TableRow extends Component {
      handleChange = e => {
        this.props.onNameUpdate(this.props.data.id, e.target.value);
      };
    
      render() {
        const {
          data: { id, name, age }
        } = this.props;
    
        return (
          <tr>
            <td>{id}</td>
            <td>{name}</td>
            <td>{age}</td>
            <td>
              <input type="text" value={name} onChange={this.handleChange} />
            </td>
          </tr>
        );
      }
    }
    
    export default App;
    

    希望这会有所帮助!祝你好运!

    【讨论】:

    • 感谢您的快速回答。您的方法在技术上似乎很稳健。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 2019-08-03
    • 2020-06-06
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多