【问题标题】:How to implement the Context API with a dynamic number of states?如何实现具有动态状态数的 Context API?
【发布时间】:2019-12-12 16:54:52
【问题描述】:

数组listOfComponents 中的组件数应该是动态的。在我的应用程序中,组件在应用程序运行时会随着时间的推移而添加和删除。当我添加一个新组件时,我想在我的ExampleContextlistOfComponents 数组中为其添加一个状态。当我删除一个组件时,我想删除状态。仅当 listOfComponents 中的设置在 id 匹配的位置更新时,该组件才应重新呈现。我将如何实施?

import React, { createContext, useState } from 'react'

export const ExampleContext = createContext()
export const { Consumer: ExampleConsumer } = ExampleContext

export function ExampleProvider({ children }) {
  const [state, setState] = useState({
    listOfComponents: [{
        id: 1,
        settings: {color: 'red'}
    },
    {
        id: 2,
        settings: {color: 'blue'}
    },
    {
        id: 3,
        settings: {color: 'green'}
    }]
 })
  return (
    <ExampleContext.Provider value={[state, setState]}>
      {children}
    </ExampleContext.Provider>
  )
}

export function Component({id}) {
  const [state, setState] = useContext(ExampleContext)
  return (
    <h1> Only rerender me if settings of matching id are updated! </h1>
  )
}

【问题讨论】:

  • 我之前做过几个 cmets,但后来我意识到当你说“状态”时我不太明白你的意思。有什么办法可以做一个小例子吗?因为我很确定,如果使用得当,更改一小部分上下文不应该强制每个组件重新渲染
  • 阅读this guide,了解即使在非常小的更改之后如何也不进行上下文重新渲染
  • @TKoL 在状态下我理解状态钩子的使用,就像const [state, setState] = useState({})。只有使用 Context API 之外的状态并被更新的组件才会重新呈现。所以我想我的问题是更多地寻找一种方法来实现这些 useState 钩子的动态数量并在动态数量的组件中使用它们。或者一种仅在更新了 useState 的一部分而不是全部时才更新组件的方法。
  • @TKoL 我更新了我的问题,希望它更容易理解

标签: javascript reactjs react-hooks react-state-management


【解决方案1】:

这是我如何使用useMemo。也许它对其他人有帮助,因为我花了一些时间才弄清楚。 this 的博文也很有帮助。如果有更好的方法请告诉我。

-- App.js

import React, {useContext, useMemo} from 'react';
import {ExampleContext, ExampleProvider} from './Context'

export function Component({id}){
  const [state, setState] = useContext(ExampleContext)

  function onClick(){
    setState(prev => {
      return {...prev, [id]: { color: 'blue'}}
    })
  }

  return useMemo(() => {
    console.log(`update ${id}`)
    return (
      <>
        <h1 style={{color: state[id].color}}>{id}</h1>
        <button onClick={onClick}>{`Update from ${id}`}</button>
      </>
    )
  }, [state[id]])
}

function App() {
  return (
    <ExampleProvider>
        <Component id={1}/>
        <Component id={2}/>
    </ExampleProvider>
  );
}

export default App;

-- Context.js

import React, { createContext, useState } from 'react'

export const ExampleContext = createContext()
export const { Consumer: ExampleConsumer } = ExampleContext

export function ExampleProvider({ children }) {
  const [state, setState] = useState({
    '1': {color: 'red'},
    '2': {color: 'green'},
  })
  return (
    <ExampleContext.Provider value={[state, setState]}>
      {children}
    </ExampleContext.Provider>
  )
}

【讨论】:

    猜你喜欢
    • 2019-09-11
    • 2011-04-21
    • 1970-01-01
    • 2020-08-14
    • 2022-06-15
    • 2021-03-04
    • 2021-12-25
    • 2019-09-03
    • 2020-10-28
    相关资源
    最近更新 更多