mzingaye nkala
mzingaye nkala

Reputation: 27

How to handle async state updates in react

I am working on a colour generator application and what I am trying to do is to update the state on mount. I understand that the updating state is asynchronous, so I have a loading state to display "loading" to the user if loading is true whilst we wait for colourOne to be defined, however I keep getting this error.

How can I wait for the value of colourOne to be defined so my Card component doesn't show the prop type warning? and in general what is the best way to showing loading states and wait on async state updates in React.

index.js:1 Warning: Failed prop type: The prop `colour` is marked as required in `Card`, but its value is `null`

   const [loading, setLoading] = useState(false);
   const [colourOne, setColourOne] = useState(null)

   const generateColour = () => {
     return (
       "#" +
       Math.floor(Math.random() * 16777215)
         .toString(16)
         .padStart(6, "0")
     );
   };

   useEffect(() => {
     setLoading(true);
     setColourOne(generateColour());
     setLoading(false);
   }, []);

   if (loading) {
     console.log("is loading");
     return <p> Loading</p>;
   }
   return (
     <ThemeProvider theme={theme}>
       <div id="App">
         <Title>Colour Palette Generator</Title>
         <CardListWrapper>
           <Card colour={colourOne} />
         </CardListWrapper>
       </div>
     </ThemeProvider>
   );
 }

export const Card = ({ colour }) => {
  return (
    <CardWrapper>
      <GeneratedColour colour={colour} />
    </CardWrapper>
  );
};

Card.propTypes = {
  colour: PropTypes.string.isRequired,
};

Upvotes: 0

Views: 193

Answers (1)

Itay Moav -Malimovka
Itay Moav -Malimovka

Reputation: 53597

The error is clear. You need to give a string default value to the colour

const [colourOne, setColourOne] = useState("someDefaultValue")

Because you gave a rule that it must be a valid string (Which NULL is not)

colour: PropTypes.string.isRequired,

Another option is not to render the pallet if there is no colour

{colourOne && (<CardListWrapper>
           <Card colour={colourOne} />
         </CardListWrapper>)}

Upvotes: 1

Related Questions