繁体   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