簡體   English   中英

如何從自定義掛鈎獲取狀態以更新“父”組件?

[英]How to get state from custom hooks to update in "parent" component?

我試圖將一些邏輯從我的組件中分離到一個自定義鈎子中。 我覺得我誤解了一些基本原理,但我認為我的代碼會起作用。 我基本上在我的自定義useTrip鈎子中更新我的狀態,並且我希望我的map組件具有相同的更新狀態。

使用Trip.js

export const useTrip = () => {
    const [businesses, setBusinesses] = useState([])
    useEffect(()=>{
        console.log(businesses) //prints expected results
    },[businesses])
    const fetchData = async (name, lat, lng) => {
        const response = await fetch('http://localhost:5000/category/' + lat + "/" + lng + '/' + name)
        const result = await response.json();
        setBusinesses(result)
    }
 return { businesses, fetchData } 
}

Map.js(使用 useTrip 的組件)

export const Map= (props) => {
    const {businesses} = useTrip()
    return(<>
        {businesses.map((.....)}
    </>)
}

Parent.js(map.js 的父級)

export const Parent= (props) => {
    const {fetchData} = useTrip()
    useEffect(() => {
        fetchData(title, lat, lng)
    }, [origin])
    return(<>
        
    </>)
}

Map組件中時, businesses總是一個空數組。 在我開始重構之前,我的代碼正在運行。 自定義鈎子中的更新狀態是否應該在使用它的組件之間保持一致? 任何幫助和建議表示贊賞。 提前ty

您必須在Parent組件上使用自定義掛鈎,並通過道具將bussinesses到您的Map組件。

IE

function Parent (props) {
  const { fetchData, bussinesses } = useTrip()

  useEffect(() => {
        fetchData(title, lat, lng)
  }, [origin])

  return (
    <Map bussinesses={bussinesses}>
  )
}

function Map (props) {
  const { bussinesses } = props
  return (
    <>
      {businesses.map(/* ... */)}
    </>
  )
}

如果您在每個組件上調用自定義鈎子,它們將獲得自己的狀態

這就是我們設法解決這個問題的方法,它並不完美,我願意接受改進建議。 但是我們創建了一個用戶組件來在整個應用程序中共享我們的用戶。

 const users = {client: {isSet: () => { return false; } } } const instances = {client: []} export const useClientUser = (defaultUser) => { const [updateId, setUpdateId] = useState(uuidv4()); const setClientUser = (data) => { users.client = new Person(data); } const updateScreen = () => { setUpdateId(uuidv4()); } useEffect(()=>{ if(defaultUser !== '' && typeof defaultUser !== 'undefined'){ setClientUser(defaultUser); } instances.client.push(updateScreen); }, []); return [users.client , (data) => { setClientUser(data); instances.client = instances.client.filter((value)=> { if(typeof value !== 'undefined'){ return true } else { return false } } ); instances.client.map((value)=> {if(typeof value !== 'undefined') { value() } }) } ]; }

我已經重寫了我們的組件,以展示您的組件將如何工作。

 import { v4 as uuidv4 } from 'uuid'; //create super globals to share across all components const global_hooks = {businesses: {isSet: false } } const instances = {businesses: []} export const useTrip = () => { //use a unique id to set state change of object const [updateId, setUpdateId] = useState(uuidv4()); //use this function to update the state causing a rerender const updateScreen = () => { setUpdateId(uuidv4()); } //when this component is created add our update function to the update array useEffect(()=>{ instances.businesses.push(updateScreen); }, []); useEffect(()=>{ console.log(global_hooks.businesses) //prints expected results },[updateId]); const fetchData = async (name, lat, lng) => { const response = await fetch('http://localhost:5000/category/' + lat + "/" + lng + '/' + name) const result = await response.json(); global_hooks.businesses = result; global_hooks.businesses.isSet = true; } return {businesses: global_hooks.businesses, fetchData: (name, lat, lng) => { //fetch your data fetchData(name, lat, lng); //remove update functions that no longer exist instances.businesses = instances.business.filter((value)=> { if(typeof value !== 'undefined'){ return true } else { return false } } ); //call update functions that exist instances.businesses.map((value)=> {if(typeof value !== 'undefined') { value() } }) } }; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM