Возможно ли React.useState(() => {}) в React?

можно ли использовать function в качестве состояния моего компонента React?

пример кода здесь:

// typescript 
type OoopsFunction = () => void;

export function App() {
    const [ooops, setOoops] = React.useState<OoopsFunction>(
        () => console.info('default ooops')
    );

    return (
        <div>
            <div onClick = { ooops }>
                Show Ooops
            </div>

            <div onClick = {() => {
                setOoops(() => console.info('other ooops'))
            }}>
                change oops
            </div>
        </div>
    )
}

но это не работает ... defaultOoops будет вызываться в самом начале, а при нажатии change oopsotrher ooops сразу же будет записываться в консоль, а не регистрироваться после повторного нажатия Show Ooops.

Зачем ?

Могу ли я использовать функцию в качестве состояния моего компонента?

или у React есть свои особые способы обработки таких the function state?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
65
0
31 962
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Можно установить функцию в состояние с помощью хуков, но поскольку состояние может быть инициализировано и обновлено с помощью функции, которая возвращает начальное состояние или обновленное состояние, вам необходимо предоставить функцию, которая, в свою очередь, возвращает функцию, которую вы хотите поместить. состояние.

const { useState } = React;

function App() {
  const [ooops, setOoops] = useState(() => () => console.info("default ooops"));

  return (
    <div>
      <button onClick = {ooops}>Show Ooops</button>

      <button
        onClick = {() => {
          setOoops(() => () => console.info("other ooops"));
        }}
      >
        change oops
      </button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src = "https://unpkg.com/react@16/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id = "root"></div>

Это было абсолютным спасением жизни! И, насколько я могу судить, без документов. Не мог понять, почему мои сохраненные функции не выполнялись. Мне нравится, что setState принимает функцию при настройке, но необходимость знать, как обернуть функцию в функцию, чтобы сохранить ее как состояние, в лучшем случае неинтуитивна. Спасибо Спасибо спасибо! Никогда бы не догадался об этом...

sambecker 27.12.2019 07:11

Это тоже было спасением для меня. Моя проблема заключалась в том, что функция, которую я устанавливал в качестве переменной состояния, срабатывала без вызова. Хранение его как функции, которая возвращает эту функцию, работает как шарм. Я согласен, что это нигде не задокументировано в документации по реакции. Спасибо!

Seth Lutske 01.10.2020 07:15

Может быть, они не были задокументированы в прошлом, но теперь они есть. См. раздел Ленивое начальное состояние, а также желтую рамку над ним, касающуюся объединения обновлений, также известного как использование prevState. Мне также была полезна эта статья: medium.com/swlh/…

Tyler Collier 25.04.2021 07:02

TL;DR

Да, можно использовать функцию в качестве состояния компонента React. Для этого необходимо используйте функцию, возвращающую вашу функцию в React.useState:

const [ooops, setOoops] = React.useState<OoopsFunction>(
    () => () => console.info('default ooops')
);

// or

const yourFunction = () => console.info('default ooops');
const [ooops, setOoops] = React.useState<OoopsFunction>(
    () => yourFunction
);

Чтобы обновить свою функцию, вы также должны используйте функцию, возвращающую вашу функцию:

setOoops(() => () => console.info("other ooops"));

// or

const otherFunction = () => console.info("other ooops");
setOoops(() => otherFunction);

Подробный ответ

Заметки о React.useState

Подпись useState в React с типами:

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];

Это показывает, что есть два способа установить начальное значение в вашем состоянии:

  1. Укажите начальное значение как есть (React.useState(0) - начальное значение 0),
  2. Предоставьте функцию, которая возвращает начальное значение для установки (React.useState(() => 0) - начальное значение также 0).

Важно отметить: если вы предоставляете функцию в React.useState, то эта функция выполняется, когда выполняется React.useState, и возвращаемое значение сохраняется как начальное состояние.

Как на самом деле хранить функции

Проблема здесь в том, что если вы хотите сохранить функцию как состояние, вы не можете предоставить ее как начальное состояние как есть, потому что это приводит к выполняемая функция и ее возвращаемое значение, хранящееся как состояние, а не сама функция. Поэтому, когда вы пишете

const [ooops, setOoops] = React.useState<OoopsFunction>(
    () => console.info('default ooops')
);

'default ooops' регистрируется сразу же при вызове React.useState и сохраняется возвращаемое значение (в данном случае undefined).

Это может быть избежать, предоставив функцию более высокого порядка, возвращающую вашу функцию, которую вы хотите сохранить:

const [ooops, setOoops] = React.useState<OoopsFunction>(
    () => () => console.info('default ooops')
);

Таким образом, внешняя функция обязательно будет выполнена при первом запуске React.useState, и ее возвращаемое значение будет сохранено. Поскольку это возвращаемое значение теперь является вашей необходимой функцией, эта функция будет сохранена.

Примечания о функции установки состояния

Сигнатура функции установки состояния (здесь setOoops) задается как

Dispatch<SetStateAction<S>>

с участием

type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);

Как и в React.useState, также есть возможность обновить состояние значением или функцией, возвращающей значение. Таким образом, для обновления состояния необходимо также использовать функцию более высокого порядка сверху..

Предыдущие ответы поставили меня на правильный путь, но мне нужно было немного изменить параметры setState, так как я хотел выполнить функцию с параметрами. Следующее сработало для меня!

const [handler, setHandler] = useState(() => {});

setHandler(() => () => enableScheduleById(scheduleId));

Другие вопросы по теме