React JS访问嵌套在状态中的数组

时间:2018-01-30 12:38:23

标签: javascript arrays reactjs state react-props

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

上面的代码可以正常工作并存储所有正确的值。但是我想在fields {}内移动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)?我将它们分开,因为它们处理两种不同的类型(字符串和数组)。

感谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

为什么不能通过以下方式完成此操作。

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
    })
  }

永远不要在render中进行setState。你不应该在render中做setState。事件处理程序应在render方法之前处理,但不在render内部处理。尽量避免在render中进行setState。

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