【问题标题】:React JS accessing an array nested in stateReact JS 访问嵌套在状态中的数组
【发布时间】:2018-01-30 12:38:22
【问题描述】:
class CreateEventForm extends Component {
  constructor(props) {
    super(props)
    this.state = {
      fields: {
        name: '',
        location: '',
        description: '',
        datetime: '',
      },
      friendsInEvent: [],
    },
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const { checked, value } = e.target
    let { friendsInEvent } = { ...this.state }
    if (checked) {
      friendsInEvent = [...friendsInEvent, value]
    } else {
      friendsInEvent = friendsInEvent.filter(el => el !== value)
    }
    this.setState({ friendsInEvent }, () => console.log(this.state))
  }

  render() {

    const { friends, createEvent, addFriendsToEvent } = this.props
    const { fields: { name, location, description, datetime } } = this.state

    const setter = propName => event => {
      const nextFields = { ...this.state.fields }
      nextFields[propName] = event.target.value
      this.setState({ fields: nextFields })
    }

    return (
      <div {...cssForm}>
        <div>
          <Label label="Event Name" />
          <Field onChange={setter('name')} />

          <Label label="Event Date/Time" />
          <Field onChange={setter('datetime')} type="datetime-local" />

          <Label label="Event Location" />
          <Field onChange={setter('location')} />

          <Label label="Event Description" />
          <Field onChange={setter('description')} />

            <SubHeader title="Add Friends to the Event..." />
              <div>
                {friends
                  .mapEntries(([friendId, frn]) => [
                    friendId,
                    <div key={friendId}>
                      <input
                          value={friendId}
                          type='checkbox'
                          onChange={this.handleChange}
                          defaultChecked={false} />
                      {frn.firstName} {frn.lastName}
                    </div>,
                  ])
                  .toList()}
              </div>

            <Link to="/">
                <Button style="blue" name="Done" onClick={() => createEvent(this.state.fields)} />
            </Link>
        </div>
      </div>
    )
  }
}

export default CreateEventForm

上面的代码按预期工作并存储所有正确的值。但是我想将friendsInEvent []移到字段{}内。看起来像:

super(props)
 this.state = {
  fields: {
    name: '',
    location: '',
    description: '',
    datetime: '',
    friendsInEvent: [],
  },   
},
  this.handleChange = this.handleChange.bind(this);
}

我怎样才能做到这一点?我尝试过的所有操作都会破坏 handleChange(e) 函数或用 friendsInEvent 数组覆盖字段{}。

我假设在 this.state.field 中移动数组后,我必须更改 handleChange(e) 函数中的值?

另外,有没有办法合并我的两个函数 setter 和 handleChange(e)?我将它们分开,因为它们处理两种不同的类型(字符串和数组)。

谢谢。

【问题讨论】:

  • 你什么时候在字段中移动friendsInEvent,是动态完成的
  • 对,它是特定于状态的,如果你需要更新下一个属性,你应该复制整个对象fields,更新它,然后才使用 setState。不确定你的 setter 做了什么,但在每个 render 上创建它绝对是个坏主意,你实际做了什么

标签: javascript arrays reactjs state react-props


【解决方案1】:

从外观上看,您需要对handleChange 进行以下更改:

handleChange(e) {
  const { checked, value } = e.target;

  // Ensure that you're destructuring from fields
  let { friendsInEvent } = { ...this.state.fields };
  if (checked) {
    friendsInEvent = [...friendsInEvent, value];
  } else {
    friendsInEvent = friendsInEvent.filter(el => el !== value)
  }

  // You need to take a copy of state, and then supply a new copy
  // of the the fields property which takes a copy of the old fields
  // property, and overwrites the friendsInEvent with the new data
  this.setState({
    ...this.state,
    fields: {...this.state.fields, friendsInEvent }
  }, () => console.log(this.state));
}

Here's a small React-free example of how this would work.

【讨论】:

    【解决方案2】:

    为什么你不能用下面的方式来做。

    handleChange(e) {
        const { checked, value } = e.target
        let { friendsInEvent } = { ...this.state }
        if (checked) {
          friendsInEvent = [...friendsInEvent, value]
        } else {
          friendsInEvent = friendsInEvent.filter(el => el !== value)
        }
        let object = {};
        object.name = this.state.name;
        object.location = this.state.location;
        object.description = this.state.description;
        object.datetime = this.state.datetime;
        object.friendsInEvent = friendsInEvent;
        this.setState({
            fields: object
        })
      }
    

    永远不要在渲染中执行 setState。您不应该在渲染中执行 setState。事件处理程序应该在渲染方法之前处理,而不是在渲染内部。尽量避免在渲染中执行 setState。

    const setter = propName => event => {
          const nextFields = { ...this.state.fields }
          nextFields[propName] = event.target.value
          this.setState({ fields: nextFields })
        }
    

    【讨论】:

      猜你喜欢
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 2021-09-03
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多