如何使用onchange使用TextField中的值设置状态数组

时间:2018-10-18 23:15:42

标签: reactjs

我是新手,正在尝试在数组中添加字符串值。我正在使用Material-UI对象。

我的状态是

this.state: {
  roles: []
}

按钮将角色中未定义的元素按下,从而增加其长度。

  clickAddRole = () => {
    this.setState({roles: this.state.roles.concat([undefined]) });
  };

所以现在我们对角色数组有一定的长度。 文本字段是使用

生成的
      this.state.roles.map((item, i)=> {
        return (
          <TextField id={'roles['+i+']'} label={'role '+i} key={i} onChange={this.handleChange('roles['+i+']')}  />
        )
      })

onchange事件的处理方式如下

  handleChange = name => event => {
    console.log(name);
    this.setState({[name]: event.target.value});
    console.log(this.state.roles);
  }

console.log语句生成的输出类似

roles[0]
[undefined]

我希望

roles[0]
["somedata"]

这里出了什么问题?没有在角色数组中设置数据。

整个代码文件是

const styles = theme => ({
  error: {
    verticalAlign: 'middle'
  },
  textField: {
    marginLeft: theme.spacing.unit,
    marginRight: theme.spacing.unit,
    width: 300
  },
  submit: {
    margin: 'auto',
    marginBottom: theme.spacing.unit * 2
  }
})

class AddModule extends Component {
  constructor() {
    super();
    this.state = {
      roles:[],
      open: false,
      error: ''
    }
  }

  clickSubmit = () => {
    const module = {
      roles: this.state.roles || undefined
    }
    create(module).then((data) => {
      if (data.error) {
        this.setState({error: data.error})
      } else {
        this.setState({error: '', 'open': true});
      }
    })
  }

  clickAddRole = () => {
    this.setState({roles: this.state.roles.concat([undefined]) });
  };

  handleChange = name => event => {
    console.log(name);
    this.setState({[name]: event.target.value});
    console.log(this.state.roles);
  }
  render() {
    const {classes} = this.props;
    return (
      <div>
            <Button onClick={this.clickAddRole} >Add Role</Button>
            {
              this.state.roles.map((item, i)=> {
                return (
                  <TextField className={classes.textField} id={'roles['+i+']'} label={'role '+i} key={i} onChange={this.handleChange('roles['+i+']')}  />
                )
              })
            }
      </div>
    )
  }
}

3 个答案:

答案 0 :(得分:0)

我有问题(也许是暂时的)。 我一个数组元素是数组的子元素。因此,更改array-element中的数据不需要setState。

这就是我所做的。...

  handleRolesChange = name => event => {
    const i = [name];
    this.state.roles[i]=event.target.value;
  }

我还将Textfield onchange参数更改为 onChange = {this.handleRolesChange(i)} 其中i是map函数中从零开始的索引。

所有这些都可以按我的需要完美地工作。 但是,如果您认为我通过跳过setState更改了角色数组,那么我将保持问题的答案,并等待正确且合法的答案。

非常感谢您的支持人员。 我们必须尝试找到解决此类基本问题的解决方案。 :)

答案 1 :(得分:0)

我认为您使整个代码有些复杂,为每个输入字段创建名称。我要做的就是更改handleRolesChangehandleChange(不确定是否更改了名称)方法,以便它采用index而不是name

handleRolesChange = index => event => {
  const { roles } = this.state;
  const newRoles = roles.slice(0); // Create a shallow copy of the roles
  newRoles[index] = event.target.value; // Set the new value
  this.setState({ roles: newRoles });
}

然后将render方法更改为如下形式:

this.state.roles.map((item, index) => (
  <TextField 
    id={`roles[${index}]`}
    label={`role ${index}`}
    key={index}
    onChange={this.handleRolesChange(index)}  
  />
))

答案 2 :(得分:0)

您是否确定未设置?来自React的docs

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即发生潜在的陷阱。相反,使用   componentDidUpdate或setState回调(setState(updater,   回调)),保证在更新后都会触发   已应用。如果您需要根据之前的状态设置状态   状态,请阅读下面的updater参数。

通常在设置代码的同一块中记录状态会打印上一个状态,因为在console.log触发时状态实际上并未更新。

我建议使用React Dev Tools来检查状态,而不要依赖console.log。