选择字段没有按状态填入(附代码)

64 阅读2分钟

我创建了一个有多个状态控制的输入字段的页面,但我很难保证在删除一排元素后,它们在前端保留正确的文本值。

这里是组件的图片

这里是显示输入的组件:

<InputContainer>
              <PrimaryLabel>Criteria</PrimaryLabel>
              {currentRuleCriteria.map((criteria, index) => (
                  <TripleInputContainer>
                      <StyledTriplePrimarySelect name="criteria-column" id="criteria-column-select" value={currentRuleCriteria[index].column} onChange={(e) => handleCriteriaColumnChange(index, e.target.value)}>
                          {columns.map((option, index) => (
                              <option key={index} value={option.value}>
                                  {option.text}
                              </option>
                          ))}
                      </StyledTriplePrimarySelect>
                      <StyledTriplePrimarySelect name="criteria-operator" id="criteria-operator-select" value={currentRuleCriteria[index].operator} onChange={(e) => handleCriteriaOperatorChange(index, e.target.value)}>
                          {criteriaOperators.map((option, index) => (
                              <option key={index} value={option.value}>
                                  {option.text}
                              </option>
                          ))}
                      </StyledTriplePrimarySelect>
                      <InputTypeSelectorsContainer>
                          <StyledColumnIcon active={criteria.valueType === "column"} onClick={() => handleCriteriaValueTypeChange(index, "column")} />
                           <StyledTextIcon active={criteria.valueType === "text"} onClick={() => handleCriteriaValueTypeChange(index, "text")} />
                      </InputTypeSelectorsContainer>
                      { criteria.valueType === "column" ? (
                          <StyledPrimarySelect name="criteria-value" id="criteria-value-select" value={currentRuleCriteria[index].value} onChange={(e) => handleCriteriaValueChange(index, e.target.value)}>
                              {columns.map((option, index) => (
                                 <option key={index} value={option.value}>
                                      {option.text}
                                 </option>
                              ))}
                          </StyledPrimarySelect>
                      ) : (
                          <StyledPrimaryInput type="text" placeholder="" value={currentRuleCriteria[index].value} onChange={(e) => handleCriteriaValueChange(index, e.target.value)} />
                      )}
                      <RemoveItemContainer onClick={() => handleRemoveCriteria(index)}>
                          <StyledRemoveItemIcon active={currentRuleCriteria.length > 1} />
                      </RemoveItemContainer>
                   </TripleInputContainer>
              ))}
              <AdditionalEntryContainer>
                  <AdditionalEntryButton onClick={() => handleAddCriteria()}>+ Add another</AdditionalEntryButton>
              </AdditionalEntryContainer>
</InputContainer>

这里是被映射到产生输入元素的状态:

    const [currentRuleCriteria, setCurrentRuleCriteria] = useState([{
        column: "title",
        operator: "contains",
        value: "",
        valueType: "text"
    }]);

这里是与状态交互的处理函数:

    const handleCriteriaColumnChange = (index, value) => {
        const newCriteria = [...currentRuleCriteria];
        newCriteria[index].column = value;
        setCurrentRuleCriteria(newCriteria);
    };

    const handleCriteriaOperatorChange = (index, value) => {
        const newCriteria = [...currentRuleCriteria];
        newCriteria[index].operator = value;
        setCurrentRuleCriteria(newCriteria);
    };

    const handleCriteriaValueChange = (index, value) => {
        setCriteriaValue(value);
        const newCriteria = [...currentRuleCriteria];
        newCriteria[index].value = value;
        setCurrentRuleCriteria(newCriteria);
    };

    const handleCriteriaValueTypeChange = (index, value) => {
        const newCriteria = [...currentRuleCriteria];
        newCriteria[index].valueType = value;
        setCurrentRuleCriteria(newCriteria);
        setCriteriaValueType(value);
    };

    const handleAddCriteria = () => {
        setCurrentRuleCriteria([...currentRuleCriteria, {
            column: criteriaColumn,
            operator: criteriaOperator,
            value: criteriaValue,
            valueType: criteriaValueType
        }]);
        setCriteriaColumn("title");
        setCriteriaOperator("contains");
        setCriteriaValue("");
        setCriteriaValueType("text");
    };

    const handleRemoveCriteria = (index) => {
        const newCriteria = [...currentRuleCriteria];
        newCriteria.splice(index, 1);
        setCurrentRuleCriteria(newCriteria);
    };

问题是什么?

我可以看到,当我添加一个新的标准时,会添加一组新的输入字段。同样地,当我编辑数值时,状态总是被正确地维护。我遇到的问题是当删除一个预先存在的元素行时。

如果我有两个标准,如上图所示,我选择第一个要删除的标准--状态更新正确,但是错误的输入字段似乎在前端被删除了,所以它不再与状态值保持一致。在这个例子中,下面的内容将是可见的。

我不明白这一点,因为输入字段应该是通过对currentRuleCriteria 状态值的映射来生成的。

我尝试了很多方法来试图纠正这个问题,但似乎无法解决。我以前没有在单个选择元素上指定值,和现在的情况一样。添加一个值字段和引用状态并没有改变任何东西,所以我相信选择字段没有被状态值填充

有什么想法吗?谢谢你