The best way to describe question is my code:
function EstateParamsList({ estateType, category }) { const [isLoading, setIsLoading] = useState(true) const [params, setParams] = useState({}) const [showPopUp, setShowPopUp] = useState(false) useEffect(() => { if (category && typeof category.id !== undefined) { return db.collection(`dictionaries/ESTATE_PARAMS/${estateType}/${category.id}/params`).onSnapshot(response => { const paramsObject = {} response.forEach(param => { paramsObject[param.id] = { ...convertParamObjetcToFieldsConfig(param.data()), change: fieldChangedHandler } }) setParams(paramsObject) setIsLoading(false) }) } else { setIsLoading(false) } }, [category]) console.log(params) const fieldChangedHandler = (event, fieldIdentifier) => { if(params) console.log(params) }
So i have params variable, that im init with object, that i’m getting async from firebase. Implementation of initializing you can see in useEffect method. For every object i want to pass ref for the function “fieldChangedHandler”, for managing value of inputs.
fieldChangedHandler is a method of my EstateParamsList. But there i cant get value of params!
Question is WHY? I’m calling fieldChangedHandler only after everything was rendered, and async request was done.
Below is console log of params. Why in func is empty params?
Calling:
const renderParamsAsFields = params => { const fields = [] for (const key in params) { fields.push(<Field {...params[key]} changed={event => params[key].change(event, key)} />) } return fields.length ? fields : <div className='EstateParamsManager-EmptyValues'>Нет параметров</div> }
Advertisement
Answer
Why not use curried function?
const createFieldChangedHandler = ( params, fieldIdentifier ) => event => { if (params) console.log(params); }; function EstateParamsList({ estateType, category }) { //... other code useEffect(() => { //...other code change: createFieldChangedHandler( paramsObject, param.id ), //...other code }, [category, estateType]);//fixed missing dependency
When you call the change function you should already have the right values in scope:
<Field {...params[key]} changed={params[key].change} />