Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

reactjs - How to update, extend arrays by using useState in React -TypeScript?

Please help me out. I want to add dynamically extra input fileds and save the values into textValues state.
Here is what I tried until now:

const [textValues, setTextValues] = useState([]);
const [numberOfTexts, setNumberOfTexts] = useState(5); <--- this value will be change dynamically
{[...Array(numberOfTexts)].map((x, i) => (
 <TextField
  style={{ marginLeft: "10px", marginTop: "10px" }}
  id="standard-basic"
  label="Text value"
  value={textValues[i]}
  onChange={(e: { target: { value: any } }) =>
  setTextValues(e.target.value)
}
/>
))}

So, in this case I want appear 5 input fields and in the textValues array to be 5 empty strings, than fill in step by step. I want to be able to increase and decrease the numberOfTexts, and update everything according to the number of texts. Thank you for your help!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For simple usecase you don't need to have 2 useState to handle the number of fields and their values.

Usually this is a best practice to define the minimal data set model.

You can write abstract function on top of setTextValues, it should do the trick ;)

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [textValues, setTextValues] = useState([]);

  const addField = () => {
    setTextValues(textValues.concat([""]));
  };

  const updateField = (index, newValue) => {
    const newValues = textValues.map((val, idx) => {
      if (idx === index) {
        return newValue;
      }
      return val;
    });

    setTextValues(newValues);
  };

  const removeField = () => {
    setTextValues(textValues.slice(0, textValues.length - 1));
  };

  return (
    <div>
      <button onClick={() => addField()}>Add field</button>
      <button onClick={() => removeField()}>Remove (last) field</button>
      <br />
      <div>
        {textValues.map((textValue, idx) => (
          <input
            style={{ marginLeft: "10px", marginTop: "10px" }}
            id="standard-basic"
            label="Text value"
            value={textValue}
            onChange={(e) => {
              updateField(idx, e.target.value);
            }}
          />
        ))}
      </div>
    </div>
  );
}

To go further, you may want to create custom hook to abstract this logic, and have reusable chunk of state. The API may look like this:

const { addField, removeField, updateField } = useInputArray(['hello', 'yo'])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...