how to set usestate value in ternery operator pass a callback functoin setState()

Viewed 32
<label htmlFor="rank" className="font-bbold">Rank:  
</label>

<InputNumber 
  id="rank" 
  value={singlepoints.rank} 
  onValueChange={(e) =>
    onRankChange(e, index)} 
  required>
</InputNumber>

{

  //  (singlepoints.rank === 0 || singlepoints.rank === null ) ? () => console.log('fjdkfhdfhd') : null


  //  ||
                                


(singlepoints.rank === 0 || 
  singlepoints.rank === null ) ?
 **(() => setInvalid(true))** && 
<small className="p-error  ml-6"> 
  Rank is required.</small>
: null


}
2 Answers

Hi this is not how you handle state change.

First to validate something you usually have onBlur event (it fires when the input looses focus)

Second instead of trying to running code in ternary you have to do it in the useEffect hook:

useEffect(() => { 
  if (singlepoints.rank === 0 || 
  singlepoints.rank === null )
     setInvalid(true)
}, [singlepoints])

However I can recommend use formik and yup to do the validation, once you figure it out it will make your life much and much easier in terms of form validation and change handling

You're off to a good start here. I see that you have a label and an InputName component, and it looks like the "rank" must be required and not zero.

I want to start by making a reference to React "controlled component" which essentially is "an input form element (for example <input />) whose value is controlled by React". The code below will give you an idea of how to rewrite your code (please note that I added a submit button to handle the conditional statement):

 import { useState } from "react";
    function App() {
    const [singlePointsRank, setSinglePointsRank] = useState("");
    const [invalid, setInvalid] = useState(false);
    
    function handleSubmit(e) {
        e.preventDefault();
        if (singlePointsRank == 0) {
           setInvalid(true);
        } else {
           //do something else if the user provides a valid answer
        }
    }
        
    return (
        <div className="App">
           <form>
             <label>Rank:</label>
             <input 
               required
               name="rank" 
               value={singlePointsRank}
               onChange={(e) => setSinglePointsRank(e.target.value)} 
             />
             <button onClick={handleSubmit} type="submit">
               Submit
             </button>
           </form>
    
        {/*The error message below will only be displayed if invalid is set to true */}
        {invalid && <p>Please provide a valid rank number.</p>}
        </div>
    );
    }
    export default App;

Note that the required property in the input element prevents the form from being submitted if it is left blank. Therefore, you do not really need to check for singlePointsRank === null.

This way React will update the state variable singlePointsRank as the user types something in it. Then, when the user clicks on the submit button, React will call the handleSubmit function to which you can add your conditional statement set your second state variable invalid to false.

Regarding ternary operator, I do not recommend using it in this case since you might want to add some extra code to your conditional statement, such as re-setting invalid back to false, removing the error message and clearing the input field to allow the user to submit another rank number.

See the example below just to give you an idea:

import { useState } from "react";
function Random2() {
const [singlePointsRank, setSinglePointsRank] = useState("");
const [invalid, setInvalid] = useState(false);

function handleSubmit(e) {
    e.preventDefault();
    if(singlePointsRank == 0) {
        setInvalid(true);
        setSinglePointsRank("");
    } else {
        // do something else and clear the input field and reset invalid back to false
        setInvalid(false);
        setSinglePointsRank("");
    }
    
}

function handleInputChange(e) {
    if(setSinglePointsRank === "") {   
        setInvalid(false);
    }
    setSinglePointsRank(e.target.value)
}

return (
    <div className="App">
       <form>
         <label>Rank:</label>
         <input 
           required
           name="rank" 
           value={singlePointsRank}
           onChange={handleInputChange} 
         />
         <button onClick={handleSubmit} type="submit">
           Submit
         </button>
       </form>

    {/*The error message below will only be displayed if invalid is set to true */}
    {invalid && <p>Please provide a valid rank number.</p>}
    </div>
);
}
export default Random2;

Again, since the main question here is regarding ternary operators and setting state, although I do not recommend using it in this case, you could rewrite the initial handleSubmit function as follows just to play around with your code:

     function handleSubmit(e) {
        e.preventDefault();
        singlePointsRank == 0 ? setInvalid(true) : console.log("do something else");  
    }

To get a little more practice, you could rewrite

 {invalid && <p>Please provide a valid rank number.</p>} 

as

{invalid ? <p>Please provide a valid rank number.</p> : ""}
Related