简体   繁体   中英

How to use useState and useEffect over array

In the code below, I have a few textareas where the user should input jsons.

I tried to use and array (well, object with numeric keys, just for the ease from rest operator assignment), and I also wanted to avoid parsing both JSONs at every change of either.

It works well, except that for the first render, I get validation only on the second json. I am pretty sure it comes down to scope, with old values being stored in the useEffect, but I added the callback versions of setErrors and that didn't work.

What am I doing wrong, and what is the right pattern for this?

PS: I intend to move each textarea into individual components of course, but would like to understand what is wrong here first.

 const [jsons, setJsons] = useState<{ [k: number]: string }>({ 0: '', 1: '' }); const [containers, setContainers] = useState<{ [k: number]: object }>({ 0: {}, 1: {} }); const [errors, setErrors] = useState<{ [k: number]: string }>({ 0: '', 1: '' }); const useContainerEffect = (index: number) => { useEffect(() => { let container = {}; try { container = JSON.parse(jsons[index]); setErrors(() => ({...errors, [index]: '' })) } catch (e) { setErrors(() => ({...errors, [index]: VALUE_IS_NOT_JSON })) } setContainers(() => ({...containers, [index]: container })) }, [jsons[index]]); } useContainerEffect(0); useContainerEffect(1); const jsonInputChange = (e: HTMLTextAreaElement, i: number) => { setJsons({...jsons, [i]: e.value }) }

Try using functional form of useState to set your errors. Also it's a good practice not to use complex dependencies in dependency array, so they can be statically checked:

  const useContainerEffect = (index: number) => {
    useEffect(() => {
      let container = {};
      try {
        container = JSON.parse(jsons[index]);
        setErrors((err) => ({ ...err, [index]: '' }));
      } catch (e) {
        setErrors((err) => ({ ...err, [index]: 'VALUE_IS_NOT_JSON' }));
      }
      setContainers(() => ({ ...containers, [index]: container }));
    }, [index]);
  };

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