0

I am new to react and hooks and I am trying to set the disabled state in the below code on the condition if state.items.length is greater than 3 but I am not getting the updated values in my state object. So I tried to set the disabled state in the useEffect hook where I get the latest values of the state. But if I setDisabled state in useEffect it goes into an infinite loop.

Can anyone tell me what is wrong with the code?

//This is how my state object and input fields looks.
 const [state, setState] = useState({
    items: [],
    value: "",
    error: null
  });

  <input
        className={"input " + (state.error && " has-error")}
        value={state.value}
        placeholder="Type or paste email addresses and press `Enter`..."
        onKeyDown={handleKeyDown}
        onChange={handleChange}
        onPaste={handlePaste}
      />


 const handleKeyDown = evt => {
    if (["Enter", "Tab", ","].includes(evt.key)) {
      evt.preventDefault();

      var value = state.value.trim();

      if (value && isValid(value)) {
        setState(prev => ({
          ...prev,
          items: [...prev.items, prev.value],
          value: ""
        }));
      }
      //if my items array which is a count of emails i.e arrays of strings is greater than 3 I want to disable the input field.
       if(state.items.length > 3){
        setDisabled(true);
      }
    }
  };

  useEffect(()=>{
    // if I set the disabled state which is an object inside the state param it goes into an infinite loop.
    passStateToParent(state);
  }[state])
Rakesh
  • 65
  • 1
  • 9
  • 1
    there is `batching` concept, if you are updating mutiple state in same function every thing will be batched together and executed. when you are adding new value, you can copy the current state, then add the new item to copied array and then check the length from copied array, not from state – upog May 10 '20 at 05:19
  • Thanks for your response. Can you please provide a sample code of how it has to be done? As I am new to react . – Rakesh May 10 '20 at 05:20
  • need some more clarity on the code, the `useState` how the items are stored in the state. how you are getting the new value that need to be added – upog May 10 '20 at 05:29
  • I am referring to https://codesandbox.io/s/frosty-cloud-h270z?file=/src/App.js example where in I want to add a feature that the input box should only accept 3 email id and not more than that. I have added the state object along with the input filed. – Rakesh May 10 '20 at 05:33

1 Answers1

0

You should start by declaring a new variable to hold and keep track of the disabled state. (use another useState) Then next you should use useEffect to constantly check on the length of items in current state. I have taken code from above mentioned codesandbox as a refernce.

// use this useState hook to keep track disabled state.
const [inputDisable, setInputDisabled] = useState(false);

//use effect to check, if state item length
useEffect(() => {
  const items = [...state.items];
  if (items.length === 3) {
    setInputDisabled(true);
  }
}, [state]);

Followed by this add a new attribute named disable in your input tag and assign the value of inputDisable to it.

Refer to this codesandbox link to see the live example. https://codesandbox.io/s/vigorous-stallman-vck52?file=/src/App.js:490-523

Ashish Singh
  • 744
  • 6
  • 15
  • 1
    Thanks a lot this works for me. I have upvoted your answer. – Rakesh May 10 '20 at 06:17
  • You are welcome, you should read official docs for react hooks, they are the best to clear any kind of confusion around react hooks and it's implementation. – Ashish Singh May 10 '20 at 06:27