Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从数组中删除索引以在特定单击时作出反应_Javascript_Arrays_Reactjs - Fatal编程技术网

Javascript 如何从数组中删除索引以在特定单击时作出反应

Javascript 如何从数组中删除索引以在特定单击时作出反应,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,我正在构建一个测验/调查生成器,类似于CMS界面,它允许用户通过单击他们想要的问题类型来添加任意数量的问题 首先,我的状态在应用程序组件中设置如下: state = { components: API.components, comps: [] } “管理”屏幕上有选定数量的按钮,这些按钮将在单击时激活问题。问题来自API.components。 例如,我们有: -欢迎辞 -谢谢留言 -是还是不是 /* 1. Generate a list of buttons with onClic

我正在构建一个测验/调查生成器,类似于CMS界面,它允许用户通过单击他们想要的问题类型来添加任意数量的问题

首先,我的状态在应用程序组件中设置如下:

state = {
  components: API.components,
  comps: []
}
“管理”屏幕上有选定数量的按钮,这些按钮将在单击时激活问题。问题来自API.components。 例如,我们有: -欢迎辞 -谢谢留言 -是还是不是

/* 1. Generate a list of buttons with onClick props.addQuestion passing a fixed id via 'i' parameter */
const QuestionTypes = props => {  
  return (
    <div data-name='typequestion'>
      {props.details.map((el, i) => <div key={i}><button className="sm" onClick={() => props.addQuestion(i)}>{el.label}</button></div>)}
    </div>
  )
}
selectComponent功能有一个开关,用于传递正确的组件:

selectComponent = (key) => {
    switch(key) {
      case 0:
        return <WelcomeMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 1:
        return <ThankYouMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 2:
        return <YesNo details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      default:
        return 'Please select a component from the left side menu'
    }
  }
const ThankYouMessage = props => (

  <section className="ui-component-view" data-name="thankyou">
    <img src={ThankYouImage} alt="x" />
    <h3>Thanks for completing our form!</h3>

    <div>
      <DeleteButton deleteQuestion={props.deleteQuestion} />
    </div>
  </section>

);
下面是组件的代码示例:

selectComponent = (key) => {
    switch(key) {
      case 0:
        return <WelcomeMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 1:
        return <ThankYouMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 2:
        return <YesNo details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      default:
        return 'Please select a component from the left side menu'
    }
  }
const ThankYouMessage = props => (

  <section className="ui-component-view" data-name="thankyou">
    <img src={ThankYouImage} alt="x" />
    <h3>Thanks for completing our form!</h3>

    <div>
      <DeleteButton deleteQuestion={props.deleteQuestion} />
    </div>
  </section>

);
请参阅应用程序组件的完整代码: 类应用程序扩展了React.Component{

  state = {
    components: API.components,
    comps: [],
    multichoice: {}
  }

  selectComponent = (key) => {
    switch(key) {
      case 0:
        return <WelcomeMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 1:
        return <ThankYouMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      case 2:
        return <YesNo details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
        break;
      default:
        return 'Please select a component from the left side menu'
    }
  }

  addQuestion = key => {

    this.setState({
      comps: [...this.state.comps, this.selectComponent(key)]
    });
  }

  deleteQuestion = e => {
    const comps = [...this.state.comps]

    // 2. here I need to add something that will DELETE ONLY the component related to the delete button

    // 3. Update state
    this.setState({ comps });
  }

  render() {
    return (
      <Container>
        <Row>
          <Col>
            <h1>Survey Builder </h1>
          </Col>
        </Row>
        <Row>
          <Col lg={3} className="border-right">
          <QuestionTypes addQuestion={this.addQuestion} details={this.state.components} />
          </Col>
          <Col lg={9}>
            <Row>
              <Col lg={12}>
                <QuestionEdit comps={this.state.comps} details={this.state.components} />
              </Col>
            </Row>
          </Col>
        </Row>
      </Container>
    )
  }
}

export default App;
状态={
组件:API.components,
公司:[],
多选:{}
}
选择组件=(键)=>{
开关(钥匙){
案例0:
返回
打破
案例1:
返回
打破
案例2:
返回
打破
违约:
return“请从左侧菜单中选择一个组件”
}
}
addQuestion=key=>{
这是我的国家({
comps:[…this.state.comps,this.selectComponent(键)]
});
}
deleteQuestion=e=>{
const comps=[…this.state.comps]
//2.这里我需要添加一些东西,只删除与删除按钮相关的组件
//3.更新状态
这个.setState({comps});
}
render(){
返回(
测量建设者
)
}
}
导出默认应用程序;

您不应该将组件保持在状态内(因为这会破坏组件的生命周期,很难对它们进行比较)。相反,只需保留钥匙:

 addQuestion = key => {
  this.setState({
   comps: [...this.state.comps, key]
  });
 }
然后在
render()
中,将关键点映射到组件:

 {this.state.comps.map((key, index) => <SomeComponent    remove={() => this.removeQuestion(index)} />)}
编辑: 状态上不应包含任何组件,而应包含表示问题的对象

comps
状态应该是不可变的,这意味着每次添加或删除问题时,您都应该从当前状态的旧数组中创建一个新数组

由于您没有使用任何高级状态管理器(如Redux等),而且在这一点上您也不应该使用,因此我建议在每个问题上都有一个带有问题ID的数据atribute。单击后,您可以从单击事件所承载的目标获取问题ID,并使用它来确定问题项在
comps
状态中的位置。一旦你有了它,创建一个新的
comps
状态,方法是构造一个新的数组,这个数组没有你刚刚删除的问题

我还建议不要在这里使用开关/机箱,因为它不符合要求。我认为您会找到一种字典方法,将问题的类型映射到相应的组件,更具可伸缩性和可维护性


希望这有帮助:)

嗨,Jonaswillms,“e”正在通过按钮传递一个id,该id是固定的id号。它们与索引数组不匹配。例如,当e传递值1时(因为我单击了WelcomeMessage按钮),组件可能位于comps[]数组的索引3中,因为我添加了其他问题。所以,通过使用e,任何东西都不起作用,即使是.filter。我都试过了。我需要能够将与我单击的删除按钮相关的索引值传递给e。这有意义吗?@joe哦,我完全没有意识到:你根本不应该在州里有组件……你能详细说明一下吗?“您根本不应该在状态中有组件”是什么意思?对不起,我对这门语言不太熟悉。你能举一些例子吗?谢谢你,伙计,没有看到上面的变化。我来看看。谢谢乔纳斯,谢谢你的密码。现在每个按钮总是显示相同的组件,因为我添加了{this.removeQuestion(index)}/>)}。处理所有其他组件的最佳实践是什么?函数映射中的If语句?(与开关类似)。我的JS方法是使用连接来创建组件名称。单击一次,按钮将传递一个名为“WelcomeMessage”的常量,我将执行类似于“WelcomeMessage”的操作,但我知道它不起作用。谢谢你迄今为止的帮助。我们得到了一些东西,hi@Matti Bar Zeev,Re:switch/case,最初我想创建一个带有组件名称动态注入的通用组件,就像我在JS中所做的那样:“”。找不到反应的方法。有什么办法吗?我不熟悉字典的事,但我会调查的。Re:ID在数据-*中,如果我有10条欢迎消息,所有消息都将具有来自单击按钮的相同ID。我想使用与我刚才单击的“删除”按钮相关的comps[]索引来删除。@Joe每个组件都应该有一个不同的ID,即使它呈现相同的内容(通过数组映射来创建项目列表,每个组件都必须有自己的键,该键是从项目ID派生的,以便按预期反应呈现)。
 addQuestion = key => {
  this.setState({
   comps: [...this.state.comps, key]
  });
 }
 {this.state.comps.map((key, index) => <SomeComponent    remove={() => this.removeQuestion(index)} />)}
 removeQuestion(index) {
   this.setState(({ comps }) => ({ comps: comps.filter((_, i) => i !== index) }));
 }