【问题标题】:How to update an arrays state with onChange through Child component's input field如何通过子组件的输入字段使用 onChange 更新数组状态
【发布时间】:2018-08-14 17:55:38
【问题描述】:

我正在尝试更新处于父组件状态的数组。每个子组件都是通过父组件状态数组中的一个元素创建的。现在我有一个 onChange 处理程序,它位于我的 Parent 组件中,我将它传递给我的 Child 组件。

这里有一些与此有关的 sn-ps:

父母

class PropertyBar extends Component {
  state = {
    selectedCell: graph.selectedCell,
    cellProperties: []
  }

  onChangeHandler(e) {
    let cellProperties = [...this.state.cellProperties];
    cellProperties[e.target.name] = e.target.value;
    this.setState({cellProperties});
  }

  renderPropertyList() {
    return this.state.cellProperties.map(key => {
      return <PropertyBarItem name={key.nodeName} value={key.nodeValue} onChange={this.onChangeHandler}/>
    })
  }
}

孩子

class PropertyBarItem extends Component {
  constructor(props) {
    super(props);
  }

  onChangeHandler(e) {
    if (this.props.onChangeHandler) {
      this.props.onChangeHandler(e);
    }
  }

  render() {
    return (
      <ListItem divider={true} className="property-bar-item">
        <TextField
          id="property"
          label={this.props.name}
          value={this.props.value}
          margin="dense"
          onChange={(e) => {this.onChangeHandler(e)}}
        />
      </ListItem>
    )
  }
}

我认为我没有正确处理在子组件中传递的onChangeHandler,但我的逻辑也可能有误。

【问题讨论】:

  • 在你的父母中,当你传入你的处理程序时,你将它作为'onChange'的道具传入 onChange={this.onChangeHandler} 如果你尝试 onChangeHandler={this.onChangeHandler} 会发生什么}
  • @Crawdingle 很好,所以现在它在我开始在文本字段中输入后崩溃并给我错误'无法读取未定义的属性'cellProperties''。不要分歧,但是onChange是react中的保留字吗?

标签: javascript reactjs


【解决方案1】:

在您的子组件中,您没有正确使用 onChangeHandler 函数,因为您将它作为 onChange 的道具传递,所以它应该像下面的代码

class PropertyBarItem extends Component {
    constructor(props) {
        super(props);
        this.state = {
          input: props.value
        }
    }

    onChange = (event) =>{
        this.setState({ input: event.target.value },()=>{ // callback of setState
            this.props.onChange(this.state.input) // passing the state to parent component
        })
    }

  render() {
    return (
      <ListItem divider={true} className="property-bar-item">
        <TextField
          id="property"
          label={this.props.name}
          value={this.state.input}
          margin="dense"
          onChange={this.onChange}
        />
      </ListItem>
    )
  }
}

您还需要在父构造函数中绑定onChangeHandle 或使用类似箭头函数

  onChangeHandler = (e) => { // arrow function
     console.log(e.target.value) // check
     //let cellProperties = [...this.state.cellProperties];
     //cellProperties[e.target.name] = e.target.value;
     //this.setState({cellProperties});
  }

【讨论】:

  • 好的,现在可以正常工作了。输入字段不显示被按下的键,但它显示在我的控制台日志中。此外,它只记录按下的每个键,而不是所有键的串联。当试图输入一个已经有值的字段时,它也只会在字符串的末尾添加 1 个键,并且控制台会记录这一点。
  • 别担心!我让它工作。问题是我试图使用String 类型而不是int 访问cellProperties。由于我已将NamedNodeMap 转换为Array,因此我忘记了必须使用元素编号而不是键来访问它。我所做的是将计数器传递给.map 函数,然后将其分配给id 属性id={this.props.id.toString()},并使用它来访问我的数组中的正确元素,例如cellProperties[parseInt(e.target.id)] = e.target.value;
  • 你仍然帮助我解决了我最初的问题,即将我的 onChangeHandler 正确映射到我的子组件,所以谢谢你!
【解决方案2】:

在您的父组件中,只需将 onChange 替换为 clicked = { (e) => {this.onChangeHandler(e)} 并在您的 chlild 组件中将我们替换为 onChange= {this.props.clicked}

在你的父组件中

onChangeHandler =(e)=> {
let cellProperties = [...this.state.cellProperties];
cellProperties[e.target.name] = e.target.value;
this.setState({cellProperties});}

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2019-06-03
    • 1970-01-01
    • 2021-01-07
    相关资源
    最近更新 更多