代码之家  ›  专栏  ›  技术社区  ›  alt-rock

反应:将有状态对象连接到数组

  •  0
  • alt-rock  · 技术社区  · 7 年前

    我试图创建一个由输入动态填充的不可变状态数组。但是,我无法创建新状态并将其添加到 people 大堆正确的方法是什么?下面是该问题的JSFIDLE演示的链接。

    链接到演示 : http://jsfiddle.net/560fyjnp/1536/

    映射并返回附加数组:

    appendPerson() {
        let newPerson = {
          name: '',
          age: '',
          school: ''
        };
    
        this.setState((prevState) => ({
          people: prevState.people.concat([newPerson])
        }));
      }
    

    处理来自输入的更改:

      handleChange(e) {
        this.setState({[e.target.name]: e.target.value})
      }
    

    输入示例:

    Name: <input name="name" value={person.name} onChange={this.props.handleChange} />
    

    映射状态并显示有状态字符串:

        {this.state.people.map((person, index) =>
        <div key={index}>
         Name: {person.name}<br />
         Age: {person.age}<br />
         School: {person.school}
         <hr/>
        </div>
        )}
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Chase DeAnda    7 年前

    Working JSFiddle Here

    您需要更新 handleChange 函数接受将作为参数传入的索引。你应该 bind 中的更改处理程序 Inputs 要传入索引,请执行以下操作:

      handleChange(index, e) {
        // Make a shallow clone of your state array
        const people = [...this.state.people];
        // Update the object at the passed in index with the property name and value
        people[index] = {...people[index], [e.target.name]: e.target.value};
        this.setState({
            people
        });
      }
    

    完整示例:

    class Inputs extends React.Component {
      constructor(props) {
        super(props);
        this.state = {}
      }
    
      render() {
        return (
          <div>
            {this.props.people.map((person, index) =>
                <div key={index}>
              Name: <input name="name" value={person.name} onChange={this.props.handleChange.bind(this, index)} /><br/>
              Age: <input name="age" value={person.age} onChange={this.props.handleChange.bind(this, index)} /><br/>
              School: <input name="school" value={person.school} onChange={this.props.handleChange.bind(this, index)} />
                <hr />
              </div>
             )}
             <button onClick={ this.props.appendPerson }>Add Another Person</button>
          </div>
        );
      }
    }
    
    class People extends React.Component {
        constructor(props) {
        super(props);
    
        this.state = {
          people: [{
            name: 'Jerry',
            age: '20',
            school: 'Fun University'
          }]
        }
    
          this.handleChange = this.handleChange.bind(this);
          this.appendPerson = this.appendPerson.bind(this);
      }
    
    
      handleChange(index, e) {
        const people = [...this.state.people];
        people[index] = {...people[index], [e.target.name]: e.target.value};
        this.setState({
            people
        });
      }
    
      appendPerson() {
        let newPerson = {
          name: '',
          age: '',
          school: ''
        };
    
        //this.setState({ people: this.state.people.concat([newPerson])});
        this.setState((prevState) => ({
          people: prevState.people.concat([newPerson])
        }));
      }
    
      render() {
        return (
          <div>
            <h1>Add Person:</h1>
            <Inputs
              people={this.state.people}
              appendPerson={this.appendPerson}
              handleChange={this.handleChange}
            />
    
            <h1>People:</h1>
            {this.state.people.map((person, index) =>
            <div key={index}>
             Name: {person.name}<br />
             Age: {person.age}<br />
             School: {person.school}
             <hr/>
            </div>
            )}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <People/>,
      document.getElementById('container')
    );
    
        2
  •  1
  •   Brahma Dev    7 年前

    您必须将索引传递给handleChange。小提琴: http://jsfiddle.net/560fyjnp/1551/

    class Inputs extends React.Component {
      constructor(props) {
        super(props);
        this.state = {}
      }
    
      render() {
        return (
          <div>
            {this.props.people.map((person, index) =>
                <div key={index}>
              Name: <input name="name" data-index={index} value={person.name} onChange={this.props.handleChange} /><br/>
              Age: <input name="age" data-index={index} value={person.age} onChange={this.props.handleChange} /><br/>
              School: <input name="school" data-index={index} value={person.school} onChange={this.props.handleChange} />
                <hr />
              </div>
             )}
             <button onClick={ this.props.appendPerson }>Add Another Person</button>
          </div>
        );
      }
    }
    
    class People extends React.Component {
        constructor(props) {
        super(props);
    
        this.state = {
          people: [{
            name: 'Jerry',
            age: '20',
            school: 'Fun University'
          }]
        }
    
          this.handleChange = this.handleChange.bind(this);
          this.appendPerson = this.appendPerson.bind(this);
      }
    
    
      handleChange(e) {
        this.setState((prevState)=>{
            prevState.people[parseInt(e.target.getAttribute('data-index'))][e.target.name]= e.target.value;
          return prevState;
        })
      }
    
      appendPerson() {
        let newPerson = {
          name: '',
          age: '',
          school: ''
        };
    
        //this.setState({ people: this.state.people.concat([newPerson])});
        this.setState((prevState) => ({
          people: prevState.people.concat([newPerson])
        }));
      }
    
      render() {
        return (
          <div>
            <h1>Add Person:</h1>
            <Inputs
              people={this.state.people}
              appendPerson={this.appendPerson}
              handleChange={this.handleChange}
            />
    
            <h1>People:</h1>
            {this.state.people.map((person, index) =>
            <div key={index}>
             Name: {person.name}<br />
             Age: {person.age}<br />
             School: {person.school}
             <hr/>
            </div>
            )}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <People/>,
      document.getElementById('container')
    );
    
        3
  •  1
  •   Community Mohan Dere    5 年前

    您需要稍微更改代码才能使其正常工作。

    查看我的解决方案。 JSFiddle demo

    以下是onChange函数在 input 元素应该看起来像。

    <input name="name" value={person.name} onChange={({ target }) => this.props.handleChange(index, target.name, target.value)} />
    

    然后就有了 handleChange 作用

    handleChange(peopleIndex, name, value) {
        this.setState(prevState => {
          const editedPeople = prevState.people[peopleIndex];
          editedPeople[name] = value;
      
          return {
            people: [
              ...prevState.people.slice(0, peopleIndex),
              editedPeople,
              ...prevState.people.slice(peopleIndex + 1)
            ]
          };
        });
      }
    

    就在这里。与输入链接的独立数据结构 data-* 属性

    希望这有帮助。