简体   繁体   中英

useState not updating an array at all

I'm trying to update the state of an array with React Hooks, using an input received from a child component.

This is the code for the array I'm trying to update (in my App.js file):

 const [results, setResults] = useState([]);

  const submitHandler = newResult => {
    const newArray = [...results, newResult];
    setResults(newArray);
    console.log(newArray);
    console.log(results);
  }

The newArray is updated and logged properly, with all the items that are submitted through the child component. But the state of results is never updated, and it always logs an empty array. It should be noted that other useState hooks in my app are working properly, only the one I'm using for this array isn't working. Does anyone know what could be wrong and how can it be fixed?

If it helps, this is the code that submits the items from the child component (Shorten.js) - these hooks are working perfectly fine:

    const [urlInput, setUrlInput] = useState("");
    const [error, setError] = useState(false);

    const changeHandler = event => {
        setUrlInput(event.target.value);
    }

    const submitHandler = event => {
        event.preventDefault();

        if (urlInput === "") {
            setError(true);
        }
        else {
            setError(false);

            axios.post("https://rel.ink/api/links/", {
                url: urlInput
            })
                .then(response => {
                    const newResult = {
                        original: urlInput,
                        shortened: "https://rel.ink/" + response.data.hashid
                    }

                    props.submit(newResult);
                })
                
            setUrlInput("");
        }
    }

In your example, you cannot guarantee the results state has been updated at the point of your console.log(results) . This is because the React state update as asynchronous and applied in batches under the hood.

If you had your console.log call under const [result, setResults] = useState([]) then it will get called on every render pass, and therefore you should see the updated value logged out once the setState function has applied your new state.

For example:

const [results, setResults] = useState([]);

console.log(results);

const submitHandler = newResult => {
  const newArray = [...results, newResult];
  setResults(newArray);
  console.log(newArray);
}

should log your new state on the next render pass.

You could also put your console.log in a useEffect which will let you know for sure that React knows your results have changed.

const [results, setResults] = useState([]);

useEffect(() => {
  console.log(results);
}, [results);

const submitHandler = newResult => {
  const newArray = [...results, newResult];
  setResults(newArray);
  console.log(newArray);
}

This means your console.log(results) will only be called when results changed, rather then on every render.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM