【问题标题】:Passing React values from child to parent将 React 值从子级传递给父级
【发布时间】:2020-07-19 03:45:43
【问题描述】:

我正在努力解决可能非常简单的事情。我的父组件是一个 Search 小部件,它需要使用在单独的 Drawer 组件中定义的过滤器。目前用户可以输入一个搜索查询,调用一个API,它需要根据抽屉组件的选择器过滤结果。但是,我无法链接父母和孩子来实现这一点!!

父组件(其中包含''组件):

function SuburbSearch(props: Props) {
    const classes = useStyles();
    const [value, setValue] = React.useState<App.Suburb | null>(null);
    const [inputValue, setInputValue] = React.useState('');
    ...
    
    return (
    <Autocomplete
      id="search"
      getOptionLabel={(option) => (typeof option === 'string' ? option : option.name + ' ' + option.state)}
      filterOptions={(x) => x}
      options={options}
      ...
      ...
      renderInput={(params) => (
        <TextField
          {...params}
          label="Search for a suburb"
          ...,
            startAdornment: (
              <InputAdornment position="start">
                <Filters></Filters>
              </InputAdornment>
            ),
            endAdornment: (
              <React.Fragment>
                {loading ? <CircularProgress color="inherit" size={20} /> : null}
                {params.InputProps.endAdornment}
              </React.Fragment>
            ),
          }}
          fullWidth
        />
      )}

子组件(这是“过滤器”):

export default function Filters() {
  const classes = useStyles();
  const [state, setState] = useState(false);
  const [dollar, setDollars] = useState<number[]>([0, 20000000]);
  const [type, setType] = React.useState<string | null>('all');
  
  ...
  const list = (anchor: Anchor) => (
    <div className={classes.root} 
      role="presentation" /*onClick={toggleDrawer(false)} onKeyDown={toggleDrawer(false)}/*/>
      <Grid className={classes.main} container spacing={2}>
        <Grid className={classes.row} item xs={1} md={2} />
        <Grid className={classes.row} item xs={10} md={8}>
          <Typography className={classes.header} align='center' gutterBottom>
            Property Type
          </Typography>
          <ToggleButtonGroup value={type} onChange={handleTypeChange} exclusive>
            <ToggleButton value="all" >All</ToggleButton>
            <ToggleButton value="some" >Some</ToggleButton>
          </ToggleButtonGroup>
        </Grid>
        ...
      </Grid>
   </div>
}

【问题讨论】:

  • 你能在codeandbox中重现这个问题吗?
  • 在不知道为什么以及需要从孩子发送给父母的数据的情况下,不可能给您任何建议。生成沙箱或明确提及父子组件之间交互的所有数据及其流动方向。
  • 在 recat js 中,无法将数据从子组件发送到父组件。你可以使用 redux 和 react-redux 库来做到这一点。
  • 我会尝试重新格式化,但有点棘手,因为这些组件已经有很多代码(这让事情更加混乱)。我正在寻找的模式实际上可能非常简单......在上面我有一个“SuburbSearch”,它实际上只是一个调用 API 的搜索输入字段,并且需要过滤结果;过滤器位于一个名为“Filters”的单独抽屉组件中...但是我无法解决的是当过滤器组件关闭时如何读取 SuburbSearch 组件中的过滤器值...
  • 好的,如果您需要来自组件的某些内容,无论该组件是否安装在 DOM 中,然后将该数据放在上下文中,并在您需要的任何地方从它访问它。如果你知道 redux,那么你也可以使用它。

标签: reactjs rxjs material-ui


【解决方案1】:

您可以简单地通过将函数作为道具传递来做到这一点,如下所示:

父组件

childCallback(value) {
    // value passed from child
}

return {
    <ChildComponent passToParent={this.childCallback}/>
}

子组件

this.props.passToParent(childValue);

【讨论】:

    【解决方案2】:

    在这里,我为您提供了一些 Pure React 中的基本状态管理技术,因为到目前为止,我是通过在评论部分与您讨论来了解的。

    模式 1,直截了当

    假设你有一个组件,即comp1,它有一些道具,包括一个需要来自其直接子组件的一些数据的方法,比如说Comp2

    const Comp1 = ({ onActionOrChild }) => {
      return (
        <>
          <Comp2 onAction={onActionOrChild} />
        </>
      )
    }
    
    const Comp2 = ({ onAction }) => {
      return (
        <form onSubmit={onAction}>
          ...
        </form>
      )
    }

    简而言之,这里我们有一个组件需要一些数据,比如说一些表单数据,来自它的一个后代,所以我们将它传递给那个孩子。但是这里的问题道具钻孔Comp1 需要接收一个它从不使用的道具。

    模式 2,使用 Context API 解决 Prop Drilling

    现在,react Context API 是稳定的,这对于实现以前需要其他状态管理库的东西非常强大。

    16.3 版引入了一个新的上下文 API,它更高效、 支持静态类型检查和深度更新。 - Docs

    如果我们使用上下文 API,我们可以从组件中提取这些方法并将它们放入一个新文件中,这将创建上下文提供程序,以便应用程序中的不同组件可以相互通信,而无需传递 props通过从不使用它的中间组件,对组件进行几次降级。

    上下文.js

    export const AppContext = createContext();
    
    export AppContextProvider = ({children}) => {
    
      const onAction = () => {}
      return (
        <AppContextProvider.Provider
          value={{onAction}}
        >
        {children}
        </AppContextProvider.Provider>
      )
      
    }

    现在,如果我们需要应用程序的任何部分中的方法,我们只需连接 context API

    import { AppContext } from "./Context.js"
    
    const comp3 = ({}) => {
      const { onAction } = useContext(AppContext);
      
      return (
        <form onSubmit={onAction}>
        ...
        </form>
      )
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-09
      • 2019-12-04
      • 2020-12-31
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      相关资源
      最近更新 更多