Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
364 views
in Technique[技术] by (71.8m points)

如何手动让react组件重新挂载?

我想用自定义hook实现两组间之间共享某一个业务逻辑。

我现在有一个自定义hook:useDetailItems,和两个组件:DetailContentNumberPad,hook内会创建一个state:items,并返回state以及相关操作方法,然后NumberPadDetailContent的下三级级组件(不是直接父子关系),NumberPad新增items数组项,而DetailContent展示items

以下是相关代码:

  • useDetailItems
import {useEffect, useState} from "react";
import generateUID from "../lib/generateUID";

export type Item = {
  id: string,
  iconId: string,
  iconName: string,
  output: string,
  remark: string,
  type: 'spend' | 'income'
}

const useDetailItems = () => {
  const [items, setItems] = useState<Item[]>([])

  // initial items
  useEffect(() => {
    const localDetailItems = JSON.parse(localStorage.getItem('detailItems') || '[]')
    console.log(`set state`, localDetailItems)
    setItems(localDetailItems)
  }, [])

  useEffect(() => {
    console.log(`set storage`, items)
    localStorage.setItem('detailItems', JSON.stringify(items))
  }, [items])


  const addItem = (item: Item) => {
    setItems([...items, {...item, id: generateUID()}])
  }
  
  return {items, addItem}
}

export {useDetailItems}
  • DetailContent
...
import {useDetailItems} from "../../../../hooks/useDetailItems";

const DetailContent = () => {
  const {items} = useDetailItems()  // 使用自定义hook取得items数据
  
  return (
      <Wrapper>
        <div className="item-wrapper">
          {items.map(item => {
            return <DetailItem item={item} key={item.id}/>   
          })}
        </div>
      </Wrapper>
  )
}

export default DetailContent
  • NumberPad
const NumberPad = ()=> {

  const {addItem} = useDetailItems()     // 使用自定义hook取得增加items的操作方法
  
  ...

  const finish = (e: React.MouseEvent) => {
  
    // 增加items!!
    addItem({id: '', iconId: state.selectedIcon.id, iconName: state.selectedIcon.name, output, remark: input, type})
  }

  return (
      ...
  )
}

export default NumberPad

我知道DetailContentNumberPad他们的不会共享state,所以打算将他们的items都依赖同一个localstorage数据上。

然后现在的问题是:DetailContentNumberPad处于同一路由,所以NumberPad即使改变了数据并且数据存储在localstorage上之后,即使我手动触发DetailContent重新渲染,也不能重新创建state,所以在DetailContent中压根就不会重新走一遍hook。

react小白,我目前只能想到让DetailContent重新挂载一遍以达到重新创建state的目的,有什么方法可以实现吗?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

跨层级组件共享 state 用 provider ,用不着把 state 往 localstorage 里过一遍,你又不是要本地保存。

你既然知道他们不会共享同一份 state 那正道就是使得他们用同一份,问题就迎刃而解了。你引入 localstorage 来搭桥同步两边的 state,好家伙各种副作用不说,一个人改了,另一个人还是不知道,难不成你要监听 localstorage 变化?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...