在`useEffect`中设置useEffect挂钩的依赖关系,而不会触发useEffect

时间:2020-03-18 00:54:20

标签: javascript reactjs react-hooks

编辑:我刚刚想到,可能不需要在useEffect挂钩中重置变量。实际上,stateTheCausesUseEffectToBeInvoked的实际值可能无关紧要。出于所有目的和目的,它只是触发useEffect的一种方式。

比方说,我有一个功能性的React组件,我使用useEffect钩子对其状态进行了初始化。我打电话给服务部。我检索了一些数据。我将数据提交给状态。凉。现在,让我们说,稍后,我与同一服务进行交互,只是这次,我创建或删除单个结果项,而不是简单地检索结果列表,而是修改或删除了一个结果项,从而修改了整个结果集。我现在希望检索我先前检索的数据列表的更新副本。此时,我想再次触发我用来初始化组件状态的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。 (当前,我最终两次调用该服务-一次将赢stateThatCausesUseEffectToBeInvoked设置为true,然后在false的上下文中将其重置为useEffect时再次钩子。此变量仅出于触发useEffect的目的,使我无需在其他地方提出我在useEffect中提出的相同服务请求的目的。

有人知道如何实现吗?

2 个答案:

答案 0 :(得分:0)

您可以采取一些措施来实现与您所描述的行为类似的行为:

stateThatCausesUseEffectToBeInvoked更改为数字

如果将stateThatCausesUseEffectToBeInvoked更改为数字,则使用后无需重置它,而只需不断增加它即可触发效果。

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

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

useEffect

添加一个条件

您可以调整useEffect-body使其仅在stateThatCausesUseEffectToBeInvokedtrue的情况下运行,而不是实际更改外部逻辑。 这仍然会触发useEffect,但会立即跳出,不会引起任何不必要的请求或退回。

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

答案 1 :(得分:0)

假设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(创建一个包含它的新数组。)