Как убедиться, что константа внутри компонента вычисляется только один раз при запуске в React (Native) с хуками? - PullRequest
0 голосов
/ 19 февраля 2020

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

Я использую react-native-svg, чтобы создать довольно сложную фигуру в приложении, которое сохраняется в компоненте остается неизменным и извлекается в родительском компоненте. Этот родительский компонент затем регулярно вращается и переводится на холст, но путь сложной фигуры не меняется. Поэтому, и поскольку вычисления довольно тяжелые, я хотел бы рассчитать путь SVG для этой фигуры только в начале приложения, но не всякий раз, когда я поворачиваю или перевожу родительский компонент. В настоящее время моя структура кода выглядит следующим образом:

Компонент рисунка

const Figure = (props) => {
    const [path, setPath] = useState({FUNCTION TO CALCULATE THE SVG PATH});

    return(
        <G>
            <Path d={path} />
        </G>
    )
}

Родительский компонент

const Parent = (props) => {
    return (
        <View>
            <Svg>
                <G transform={ROTATE AND TRANSFORM BASED ON INTERACTION}>
                    <Figure />
                </G>
            </Svg>
        </View>
    )
}

As Вы можете видеть, что я использую состояние для данных пути. Мои вопросы сейчас:

  1. Я гарантирую, что этот путь рассчитывается только один раз при запуске?
  2. Есть ли более элегантный / лучший способ сделать это (например, я не использую функция сеттера вообще сейчас, так что я не думаю, что это лучшая практика)

РЕДАКТИРОВАТЬ:

Функция для расчета пути зависит от некоторых реквизитов, которые я передаю от родительского компонента.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Когда вы передаете значение в useState, это значение используется для инициализации состояния. Он не устанавливается каждый раз, когда компонент перезапускается, поэтому в вашем случае path устанавливается только при монтировании компонента.

Даже если реквизиты меняются, состояние path не будет.

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

const Figure = (props) => {
  // get relevant prop
  const { importantProp } = props;

  // path will never change, even when props change
  const [path] = useState(calculatePath(importantProp));

  return(
    <G>
      <Path d={path} />
    </G>
  )
}

Однако функция calculatePath по-прежнему оценивается при каждом рендеринге, даже если значение path не инициализируется повторно. Если calculatePath является дорогостоящей операцией, рассмотрите возможность использования useMemo вместо этого:

Вы можете убедиться, что path обновляется только при изменении указанного c реквизита, добавив этот реквизит в массив зависимостей:

const Figure = (props) => {
  const { importantProp } = props;

  const path = useMemo(() => calculatePath(importantProp), [importantProp]);

  return(
    <G>
      <Path d={path} />
    </G>
  )
}

И в этом случае вам вообще не нужно состояние.

Добавление importantProp в массив зависимостей useMemo означает, что каждый раз, когда importantProp изменяется, React пересчитает вашу переменную path.

Использование useMemo предотвратит оценку дорогостоящих вычислений при каждом рендеринге.

Я создал Пример CodeSandbox где в консоли видно, что путь пересчитывается только при изменении указанного пропеллера important. Если вы измените любой другой реквизит, path не будет пересчитан.

0 голосов
/ 19 февраля 2020

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

В вашем случае вы можете сделать что-то вроде этого:

const Figure = (props) => {
    const path = React.useMemo(() => {
      // calculate and return value for path
    }, []);

    return(
        <G>
            <Path d={path} />
        </G>
    )
}

Он был создан для этой части.

Надеюсь, это поможет;)!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...