Установка зависимости крючка useEffect в ʻuseEffect` без запуска useEffect - PullRequest
1 голос
/ 18 марта 2020

Edit: Мне просто пришло в голову, что, вероятно, нет необходимости сбрасывать переменную в хуке useEffect. На самом деле, фактическое значение stateTheCausesUseEffectToBeInvoked скорее всего несущественно. Для всех намерений и целей это просто способ запуска useEffect.

Допустим, у меня есть функциональный компонент React, состояние которого я инициализирую с помощью ловушки useEffect. Я звоню в сервис. Я получаю некоторые данные. Я фиксирую эти данные, чтобы заявить. Круто. Теперь, скажем, я позже буду взаимодействовать с той же службой, за исключением того, что на этот раз вместо того, чтобы просто получать список результатов, я СОЗДАЮ или УДАЛЯЮ один элемент результата, тем самым изменяя весь набор результатов. Теперь я wi sh, чтобы получить обновленную копию списка данных, которые я получил ранее. На этом этапе я бы хотел снова запустить хук useEffect, который использовал для инициализации состояния моего компонента, потому что я хочу перерисовать список, на этот раз с учетом вновь созданного элемента результата.

const myComponent = () => {
  const [items, setItems] = ([])
  useEffect(() => {
    const getSomeData = async () => {
      try {
        const response = await callToSomeService()
        setItems(response.data)
        setStateThatCausesUseEffectToBeInvoked(false)
      } catch (error) {
        // Handle error
        console.log(error)
      }
    }
  }, [stateThatCausesUseEffectToBeInvoked])

  const createNewItem = async () => {
    try {
      const response = await callToSomeService()
      setStateThatCausesUseEffectToBeInvoked(true)
    } catch (error) {
        // Handle error
        console.log(error)
    }
  }
}

Надеюсь, вышесказанное имеет смысл.

Дело в том, что я хочу сбросить stateThatCausesUseEffectToBeInvoked в false БЕЗ принудительного повторного рендеринга. (В настоящее время я заканчиваю тем, что вызываю службу дважды - сначала для win stateThatCausesUseEffectToBeInvoked устанавливается значение true, а затем снова, когда она сбрасывается на false в контексте ловушки useEffect. Эта переменная существует исключительно для цель вызвать useEffect и избавить меня от необходимости делать в другом месте тот же запрос на обслуживание, который я делаю в useEffect.

Кто-нибудь знает, как это может быть выполнено?

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Предполагая, что 1) под const [items, setItems] = ([]) вы подразумеваете const [items, setItems] = useState([]), и 2) что вы просто хотите отобразить последние данные после вызова API:

Когда состояние компонента обновляется , он рендерит сам по себе. Нет необходимости в stateThatCausesUseEffectToBeInvoked:

const myComponent = () => {

const [ items, setItems ] = useState( [] )

const getSomeData = async () => {
    try {
        const response = await callToSomeService1()
        // When response (data) is received, state is updated (setItems)
        // When state is updated, the component re-renders on its own
        setItems( response.data )
    } catch ( error ) {
        console.log( error )
    }
}

useEffect( () => {
    // Call the GET function once ititially, to populate the state (items)
    getSomeData()
    // use [] to run this only on component mount (initially)
}, [] )

const createNewItem = async () => {
    try {
        const response = await callToSomeService2()
        // Call the POST function to create the item
        // When response is received (e.g. is OK), call the GET function
        // to ask for all items again.
        getSomeData()
    } catch ( error ) {
        console.log( error )
    }
}                                           }

Однако вместо того, чтобы получать все элементы после каждого действия, вы можете изменить свой массив локально, поэтому, если create (POST) response.data является вновь созданным элементом, Вы можете добавить его в items (создать новый массив, который включает его).

0 голосов
/ 18 марта 2020

Есть несколько вещей, которые вы можете сделать, чтобы добиться поведения, аналогичного описанному вами:

Измените stateThatCausesUseEffectToBeInvoked на число

Если вы измените stateThatCausesUseEffectToBeInvoked на число, вам не нужно сбрасывать его после использования, и вы можете просто увеличивать его, чтобы вызвать эффект.

useEffect(() => {
  // ...
}, [stateThatCausesUseEffectToBeInvoked]);

setStateThatCausesUseEffectToBeInvoked(n => n+1); // Trigger useEffect

Добавьте условие к useEffect

Вместо того, чтобы фактически изменять любые логики c снаружи, вы можете просто настроить useEffect -тело, чтобы оно работало, только если stateThatCausesUseEffectToBeInvoked равно true. Это все равно вызовет useEffect, но выпрыгнет прямо и не вызовет ненужных запросов или повторных обращений.

useEffect(() => {
  if (stateThatCausesUseEffectToBeInvoked === true) {
    // ...
  }
}, [stateThatCausesUseEffectToBeInvoked]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...