如何将状态从钩子传递到 React 中的 App 钩子中显示?

How to pass state from hook to display in App hook in React?

如何将info的state(data)发送到App hook,这样我就可以显示div中的属性了? setInfo(info)存储了我要在Map钩子上显示的数据,我在_onClickconsole.log(info)时可以看到所有的属性。我坚持如何在应用程序中使用和显示它。感谢您的帮助。

应用程序

const App = () => {

  return (
    <div className="App">
      <div className="inner-left map-container">
        <Map />
      </div>
      <div className="inner-right info-container">
        <Nav />
        <Search />
        <div id="info_side">
          {info} // throws an error undefined
        </div>
      </div>
    </div>
  );
}

export default App;

地图

const Map = () => {
    ...
    const [info, setInfo] = useState(null)

    ...

    const _onClick = event => {
        const { features } = event;
        const info = features && features.find(f => f.layer.id === 'icon');
        setInfo(info); // This is what I would like to use in App
    }

    return (
        <ReactMapGL
            {...viewport}
            onViewportChange={_updateViewport}
            width="100%"
            height="100%"
            mapStyle={mapStyle}
            mapboxApiAccessToken={TOKEN}
            onHover={_onHover}
            onClick={_onClick}>

            <Source id="my-data" type="geojson" data={geojson}>
                <Layer {...icon} />
            </Source>

            <div style={navStyle}>
                <NavigationControl onViewportChange={_updateViewport} />
                ...
            </div>
        </ReactMapGL>
    );
}

export default Map;

您可以将回调道具传递给 child。

应用程序

const App = () => {

  const [info, setInfo] = useState(); // local info state

  const displayInfo = () => {
    // this is where I would hope to return the <div>'s with data such as <div>info.Company</div>
    // access current copy of info
  }

  return (
    <div className="App">
      <div className="inner-left map-container">
        <Map onInfoChange={setInfo} /> // pass info state setter to child
      </div>
      <div className="inner-right info-container">
        <Nav />
        <Search />
        <div id="info_side">
          {displayInfo}
        </div>
      </div>
    </div>
  );
}

export default App;

地图

const Map = ({
  onInfoChange, // passed callback prop
}) => {
    ...
    const [info, setInfo] = useState(null)

    // use an effect hook to call callback whenever info updates
    useEffect(() => {
      onInfoChange(info); // pass info back to parent
    }, [info]);

    const _onClick = event => {
        const { features } = event;
        const info = features && features.find(f => f.layer.id === 'icon');
        setInfo(info); // This is what I would like to use in App
    }

    return (
        <ReactMapGL
            {...viewport}
            onViewportChange={_updateViewport}
            width="100%"
            height="100%"
            mapStyle={mapStyle}
            mapboxApiAccessToken={TOKEN}
            onHover={_onHover}
            onClick={_onClick}>

            <Source id="my-data" type="geojson" data={geojson}>
                <Layer {...icon} />
            </Source>

            <div style={navStyle}>
                <NavigationControl onViewportChange={_updateViewport} />
                ...
            </div>
        </ReactMapGL>
    );
}

export default Map;

此时我应该指出,您现在在两个组件中存储了重复的状态,因此将信息状态和逻辑提升到最近的共同祖先 (App) 并简单地将信息作为 prop 传递是个好主意到需要它的组件(地图)。 单一事实来源原则。或者正如其他人所指出的那样,切换到全局状态管理系统,如 redux,或者使用 React Context 滚动你自己的系统(即 react-redux 在幕后使用的)。

如果多个组件共享状态,则状态应由第一个共同祖先管理并通过属性向下传递。在您的情况下,App 应该管理状态并将您需要的内容作为道具传递给 Map 。 但是我们如何根据 child 事件更新 parent 状态呢?在 parent 上创建事件处理程序,并通过 props 将其作为回调函数传递给 child 组件。

例如,在您的应用中创建回调函数函数:

const [info, setInfo] = useState({});

const handleEvent = event => {
        // Do whatever you need here
        setInfo(info); 
    }

通过 props 将信息(状态)和回调函数传递给 child:

<Map info={info} clicked={handleEvent}/> //Do not use handleEvent(), otherwise it will call the function immediately 

在地图上,使用道具并将点击设置为事件监听器:

const Map = ({info, clicked}) => { // destructuring pros.info and props.clicked

  <ReactMapGL
            {...viewport}
            onViewportChange={_updateViewport}
            width="100%"
            height="100%"
            mapStyle={mapStyle}
            mapboxApiAccessToken={TOKEN}
            onHover={_onHover}
            onClick={clicked}>

在此处查看更多信息 https://towardsdatascience.com/passing-data-between-react-components-parent-children-siblings-a64f89e24ecf