Home > Software engineering >  React - How get initial value from Backend API in useState?
React - How get initial value from Backend API in useState?

Time:12-29

I'm send some settings data in useEffect:

  const [settingsData, setSettingsData] = useState([]);
  const [settingsLoading, setSettingsLoading] = useState(true);
    
  useEffect(() => {
    if (isAuth) {
      apiClient
        .get("api/v1/page-data/settings")
        .then((response) => {
          setSettingsData(response.data);
          setSettingsLoading(false);
        })
        .catch((error) => console.error(error));
    }
  }, []);

And create useStates for two keys inputs with data from backend:

const [publicKey, setPublicKey] = useState(
    settingsData?.data?.user_data?.public_key
  );
  const [secretKey, setSecretKey] = useState(
    settingsData?.data?.user_data?.secret_key
  );

There is an inputs:

<input
  value={publicKey}
  onChange={(e) => setPublicKey(e.target.value)}
  placeholder="PublicKey"
  />
  
<input
  value={secretKey}
  onChange={(e) => setSecretKey(e.target.value)}
  placeholder="SecretKey"
 />

When page is loaded i'm just see empty inputs, looks like useState assign my backend property when it's undefined. How can i assign backend data to useState if this hook initialize initial value before my settings data is loaded from backend?

CodePudding user response:

Your key related initial states are set to undefined because the data is not available when they are created. There are a few ways to solve that, here are a couple:

  • You can set those key related values at the same time you set your data object instead of trying to derive them
  const [settingsData, setSettingsData] = useState([]);
  const [settingsLoading, setSettingsLoading] = useState(true);
  const [publicKey, setPublicKey] = useState('');
  const [secretKey, setSecretKey] = useState('');
    
  useEffect(() => {
    if (isAuth) {
      apiClient
        .get("api/v1/page-data/settings")
        .then(({ data }) => {
          setSettingsData(data);
          setSettingsLoading(false);
          setPublicKey(data.user_data.public_key);
          setSecretKey(data.user_data.secret_key);
        })
        .catch((error) => console.error(error));
    }
  }, []);
  • A less optimal option would be to use another useEffect to update your key telated states
const [settingsData, setSettingsData] = useState([]);
const [publicKey, setPublicKey] = useState('');
const [secretKey, setSecretKey] = useState('');

useEffect(() => {
  if (settingsData) {
    setPublicKey(settingsData.user_data.public_key);
    setSecretKey(settingsData.user_data.secret_key);
  }
}, [settingsData]);
  • a third option is to make only the initial state of the inputs derived from the returned data and use short circuiting to manage the value
  const [settingsData, setSettingsData] = useState([]);
  const [settingsLoading, setSettingsLoading] = useState(true);
  const [publicKey, setPublicKey] = useState('');
  const [secretKey, setSecretKey] = useState('');

  const publicK = settingsData?.data?.user_data?.public_key;
  const secretK = settingsData?.data?.user_data?.secret_key;
    
  useEffect(() => {
    if (isAuth) {
      apiClient
        .get("api/v1/page-data/settings")
        .then(({ data }) => {
          setSettingsData(data);
          setSettingsLoading(false);
          setPublicKey(data.user_data.public_key);
          setSecretKey(data.user_data.secret_key);
        })
        .catch((error) => console.error(error));
    }
  }, []);

// inputs will start with the values from const but once you write anything
// in the input it will change to the managed value in state
<input
  value={publicKey || publicK}
  onChange={(e) => setPublicKey(e.target.value)}
  placeholder="PublicKey"
/>
  
<input
  value={secretKey || secretK}
  onChange={(e) => setSecretKey(e.target.value)}
  placeholder="SecretKey"
/>
  • Related