Как обновить значение, возвращаемое функцией React (реализация useState)

#javascript #reactjs #react-native

#javascript #reactjs #реагировать-родной

Вопрос:

Допустим, у меня есть такая вещь, функция, возвращающая значение, и функция установки, как я могу правильно реализовать функцию установки, чтобы обновлять возвращаемое значение при каждом его вызове? (например, возвращаемое значение useState и функция обновления)

  const myFunction = (initialValue) => {
     let value = initialValue;
     const setterFunction = (newValue) =>{
         value= newValue;
     }
      forceRerender() //function that forces re-renders 
     return [value,setterFunction];
 }
 const [myValue,updaterFunc] = myFunction('someValue');
 updaterFunc('newValue'); // myValue's new Value should be 'newValue'
  

Ответ №1:

Если вы пытаетесь повторно реализовать то, как это делает React, вам нужно, чтобы функции настройки привели к повторному запуску всего блока — что-то вроде следующего:

 const state = [];
const App = () => {
  let stateIndex = 0; // This variable keeps track of the sequential calls to `myFunction`
                      // (Needed if myFunction gets called multiple times)
  const myFunction = (initialValue) => {
    // Assign initial value if it doesn't exist yet
    if (!state.hasOwnProperty(stateIndex)) state[stateIndex] = initialValue;
    const value = state[stateIndex];
    // Need to create a closure over the current state index...
    const closureStateIndex = stateIndex;
    const setterFunction = (newValue) => {
      state[closureStateIndex] = newValue;
      // Re-run the entire function asynchronously:
      setTimeout(App);
    };
    // Increment state index to allow for additional calls to myFunction
    stateIndex  ;
    return [value, setterFunction];
  }
  const [myValue, updaterFunc] = myFunction('initialValue');
  // Call updater only on initial render:
  if (myValue === 'initialValue') {
    updaterFunc('newValue'); // myValue's new Value should be 'newValue'
  }
  console.log('Rendering. Current value is:', myValue);
};

App();  

Это немного похоже на то, как это делает React.

Для примера с несколькими переменными состояния и переименованием myFunction в useState :

 const state = [];
const App = () => {
  let stateIndex = 0;
  const useState = (initialValue) => {
    if (!state.hasOwnProperty(stateIndex)) state[stateIndex] = initialValue;
    const value = state[stateIndex];
    const closureStateIndex = stateIndex;
    const setterFunction = (newValue) => {
      state[closureStateIndex] = newValue;
      setTimeout(App);
    };
    stateIndex  ;
    return [value, setterFunction];
  }
  const [name, setName] = useState('bob');
  const [age, setAge] = useState(5);
  if (age === 5) {
    setAge(10);
  }
  console.log('Rendering. Current name and age is:', name, age);
};

App();