setState 将对象添加到基于文本字段的数组的问题

Problem with setState adding an object to an array based off textfield

这么快就解决了问题。我正在构建一个步骤向导工具,供用户创建自定义模板。有多个步骤从用户那里获取文本输入,我的应用程序知道用户在哪个步骤上输入数据并将 stepid 分配给那段文本。 我遇到的问题是将该数据置于状态中,以便我可以根据特定格式 post 将其转换为 API。这是我希望数据看起来像的示例:

state: {
   steps : [
         {templateStepId : 'this will be the number' , data: 'this will be 
         the message'},

         {templateStepId : 'this will be the number' , data: 'this will be 
         the message'} //there could be multiple text inputs each 
                        corresponding with a different stepId
          ]

这是我的代码示例:

        addMsg = (msg , stepId) =>{
        let message = this.state.message
        message[stepId] = msg
        this.setState({message})
        this.setState( prevState => ({
            steps: [...prevState.steps,  {templateStepId: stepId, data : msg}]
        }));
    }`
Ignore the first setState, thats for something else. 
But here is where my text is coming from in another component: 

    handleChange = (text, type) =>{
        this.props.addMsg(text, type)
    }



    render() {

        return (
            <MuiThemeProvider>
                <React.Fragment>
                    <AppBar title = {this.props.text}/>
                    <TextField
                    placeholder = {this.props.text}
                    onChange = {(e) => {this.handleChange(e.target.value , e.target.name)}}
                    name= {this.props.templateStepId}
                    id = 'msg'
                    />
                    <Navigation {...this.props} ></Navigation>
                </React.Fragment>
            </MuiThemeProvider>


        )}

我也试过这个作为我的添加消息组件的解决方案:

 let newStep = {templateStepId : stepId , data: msg}
    this.setState({
        steps : [newStep]
    })

前面的代码运行良好并为我提供了我想要的状态对象,但是一旦用户移动到另一个文本输入组件,它就会被完全覆盖。

根据请求进行编辑,此处是在步骤向导中调用组件的位置。如您所见,只有一个名为消息的文本输入组件。根据来自 API 的 stepId,可以多次调用此组件,这就是为什么每个输入的 stepId 都会发生变化。

<MuiThemeProvider>
    <React.Fragment>
        <StepWizard >

        {
            this.props.templateSteps.map((data, idx) => {


            if (data.stepTypeId === "dc448967-7fad-42cf-8706-bbe1d124ceac") {

                return <Message
                addMsg = {this.props.addMsg}
                text = {data.name}
                templateStepId = {data.templateStepId}
                message = {this.props.message}
                startOver = {() => {this.props.startOver()}}
                key={idx}
            />

这是我在 devtools 控制台中的状态:

如您所见,它正在为每个字母输入创建一个新对象。在这一点上,我将不胜感激,因为我正在用头撞墙试图解决这个问题!

每次更改输入时都会调用 handleChange。这为状态增加了一步。您可以检查状态中是否存在 stepId 并将数据添加到该 stepId only.If stepId 不存在您可以添加记录。

function getStepIdIndex(arr, id) {

  for (let i = 0; i < arr.length; i++) {
    if (arr[i].templateStepId === id) {

      return i;
    }
  }
  return -1;
}

let addMsg = (msg, stepId) => {
  let stepIdIndex = getStepIdIndex(this.state.steps, stepId);
  if (stepIdIndex === -1) {
    this.setState(prevState => ({
      steps: [...prevState.steps, {
        templateStepId: stepId,
        data: msg
      }]
    }));
  } else {
    this.state.steps[stepIdIndex].data=msg;
    this.setState({steps:[...this.state.steps]});
}
}