【问题标题】:Trigger state hooks from parent to child触发从父到子的状态钩子
【发布时间】:2021-03-14 07:36:18
【问题描述】:

我有一个底部抽屉组件BottomSheetComponent,我可以使用状态挂钩从页面顶部的按钮进行切换。单击按钮将抽屉切换到视图后。但是,我无法使用 svg 图标触发从抽屉本身关闭的抽屉,并且无法弄清楚如何将状态挂钩从父组件 App 传递给子组件 BottomSheetComponent 以触发关闭子组件。

如何从子组件的svg切换子组件关闭?

App.js

function App() {
  const [toggle, setToggle] = useState(false);
  const handleToggle = () => {
    setToggle(!toggle);
  }

  return (
    <div classNameName="App">
    <button onClick={handleToggle}>Toggle Bottom Sheet</button>
      {toggle && <BottomSheetComponent toggle={toggle} header="My Custom Title" subHeader="Some more information here">
      This is the body of the component
      </BottomSheetComponent>}
    </div>
  );
}

export default App;

BottomSheetComponent.js

import { useSpring, animated, interpolate, config } from "react-spring/hooks";
const BottomSheet = (props) => {
    console.log(props)
    const theme = useTheme();
    const classes = useStyles({ theme })

    return (
       <div className={classes.bottomSheetContainer} style={{transform: 'translateY(calc(-40vh + 0px))'}}>
            <div className={classes.headerDragger}></div>
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"
                className={classes.closeButton} style={{ position: 'absolute', right: 16, top: 16 }}>
                <path d="M17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.29289 17.2929C4.90237 17.6834 4.90237 18.3166 5.29289 18.7071C5.68342 19.0976 6.31658 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071Z" fill="#191919"></path></svg>
            <h1 className={classes.header}>{props.header}</h1>
            <h2 className={classes.subHeader}>{props.subHeader}</h2>
            <div>
                <div className={classes.contentContainer}>
                    <div style={{ background: 'linear-gradient(rgb(230, 100, 101), rgb(145, 152, 229))', height: 800 }}>
                        <h1 style={{ color: '#ffffff', padding: 8, fontSize: 18 }}>
                            {props.children}
                        </h1>
                    </div>
                </div>
            </div>
        </div>
    )
}

组件的当前状态:

https://codesandbox.io/s/green-sky-n098b?fontsize=14&hidenavigation=1&theme=dark

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    handleToggle 函数传递给孩子,并将其设置为SVG 文件的onClick 处理程序:

    const { useState } = React;
    
    const BottomSheetComponent = ({ children, toggle }) => (
      <div>
        <svg
          onClick={toggle}
          height="24" width="24">
            <circle cx="12" cy="12" r="10" stroke="black" strokeWidth="3" fill="red" />
        </svg>
        
        <div>
          {children}
        </div>
      </div>
    );
    
    function App() {
      const [toggle, setToggle] = useState(false);
      const handleToggle = () => {
        setToggle(!toggle);
      }
    
      return (
        <div className="App">
        <button onClick={handleToggle}>Toggle Bottom Sheet</button>
          {toggle && <BottomSheetComponent toggle={handleToggle} header="My Custom Title" subHeader="Some more information here">
          This is the body of the component
          </BottomSheetComponent>}
        </div>
      );
    }
    
    ReactDOM.render(
      <App />,
      root
    );
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    【讨论】:

    • 既然BottomShelfComponent被导入到App.js中,那如何将prop传递给子组件呢?当我尝试时,页面变为空白。
    • 您应该将其作为道具传递(例如 - 我的代码中的 toggle={handleToggle})。
    • 我将toggle={handleToggle} 传递给&lt;BottomSheetComponent/&gt;,然后使用&lt;svg onClick={toggle}/&gt;,但它不会触发组件关闭。
    • onClick={toggle}替换为onClick={() =&gt; console.log('click')},看看控制台中是否出现click字样。如果是这样,您可能传递了错误的函数。如果它不尝试用按钮组件包装它,并将onClick 传递给按钮。
    • 我能够注销click,但我将toggle 从父toggle={handleToggle} 传递给孩子,而孩子正在使用&lt;svg onClick={toggle}/&gt;,这应该会触发功能切换孩子关门了,但事实并非如此。
    【解决方案2】:

    与您将切换作为道具传递的方式类似,您可以将 setToggle 作为道具传递给孩子。在这种情况下,孩子是您的 BottomSheetComponent。调用您的 handleToggle 应该会更新状态。

    如果您很难让 svg 触发它。你可以用一个按钮包装它,当事件冒泡时让按钮捕捉事件。您可以停止传播,然后在那里处理逻辑。

    【讨论】:

      【解决方案3】:

      对于子-父通信,您应该将设置状态的函数从父传递给子,并且每当您触发该函数时,状态都会更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-29
        • 1970-01-01
        • 1970-01-01
        • 2019-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-26
        相关资源
        最近更新 更多