将React值从子级传递到父级 [英] Passing React values from child to parent

查看:58
本文介绍了将React值从子级传递到父级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力制定出可能非常简单的方法.我的父组件是搜索"小部件,它需要使用在单独的抽屉"组件中定义的过滤器".当前,用户可以键入搜索查询,该查询调用一个API,并且它需要基于抽屉组件中的选择器来过滤结果.但是,我无法链接父母和孩子来实现这一目标!

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

  function SuburbSearch(props:Props){const classes = useStyles();const [value,setValue] = React.useState< App.Suburb |null>(null);const [inputValue,setInputValue] = React.useState('');...返回 (<自动完成id ="search"getOptionLabel = {(选项)=>(typeof option ==='string'?option:option.name +''+ option.state)}filterOptions = {(x)=>X}选项= {选项}......renderInput = {(params)=>(< TextField{... params}label =搜索郊区"...,startAdornment :(< InputAdornment position ="start"><过滤器></过滤器></InputAdornment>),endAdornment :(<反应片段>{正在加载?< CircularProgress color ="inherit" size = {20}/>: 空值}{params.InputProps.endAdornment}</React.Fragment>),}}全屏宽度/>)}

子组件(这是过滤器"):

导出默认函数 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} 容器间距={2}><网格className = {classes.row}项目xs = {1} md = {2}/><网格className = {classes.row}项目xs = {10} md = {8}><版式className = {classes.header} align ='center'gutterBottom>财产种类</Typography><ToggleButtonGroup value={type} onChange={handleTypeChange} exclusive>< ToggleButton value =全部">全部</ToggleButton>< ToggleButton value ="some"> Some</ToggleButton></ToggleButtonGroup></Grid>...</Grid></div>}  

解决方案

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

模式1,直达

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

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

简而言之,这里有一个组件,该组件需要来自其后代之一的一些数据,例如一些表单数据,因此我们将其传递给该子级.但是这里的问题 道具钻探 Comp1 需要接收一个它从未使用过的道具.

模式2,使用Context API解决道具钻探

现在,react Context API 是稳定的,它对于实现以前需要其他状态管理库的功能非常强大.

版本16.3引入了新的上下文API,该API效率更高且支持静态类型检查和深度更新.-文档

如果我们使用上下文API,则可以从组件中提取这些方法并将其放入一个新文件中,这将创建上下文提供程序,以便应用程序中的不同组件可以相互通信,而无需传递道具到从未使用过的中间组件到组件之间的几级下降.

Context.js

  export const AppContext = createContext();导出 AppContextProvider = ({children}) =>{const onAction =()=>{}返回 (< AppContextProvider.Provider值= {{onAction}}>{孩子们}</AppContextProvider.Provider>)}  

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

 从"./Context.js"导入{AppContext}const comp3 =({})=>{const {onAction} = useContext(AppContext);返回 (< form onSubmit = {onAction}>...</form>)}  

I am struggling to work out something that is likely very simply. My parent component is a Search widget, which needs to use Filters defined in a separate Drawer component. Currently the user can type in a search query, which calls an API, and it needs to filter the results based on selectors form the drawer component. However, I cannot link the parent and child to make this happen!!

The parent component (which includes the '' component within):

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
        />
      )}

The child component (this is the 'Filter'):

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>
}

解决方案

Here I'm providing you with some basic state management technique in Pure React, because so far I came to know by discussing with you in comment section.

Pattern 1, straight forward

Let's say you have a Component, comp1 namely, and it has some props including a method that requires some data from its direct child component, let's say Comp2:

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

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

In short, here we have a component that requires some data, let's say some form data, from one of its descendants, so we passed it down to that children. But the problem here is Prop drilling, Comp1 needs to receive a prop that it never uses.

Pattern 2, solving Prop Drilling with Context API

Now, react Context API is stable, which is very powerful to achieve something that used to require other state-management library.

Version 16.3 introduces a new context API that is more efficient and supports both static type checking and deep updates. - Docs

If we use context API, we can rip those methods out from the component and put them in a new file, that will create the context provider so that different component across the Application can communicate with each other, without passing down the props to the component a few level downs through the intermediate components that never use it.

Context.js

export const AppContext = createContext();

export AppContextProvider = ({children}) => {

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

Now, if we need a method in any piece of the Application we need to just hook up the context API:

import { AppContext } from "./Context.js"

const comp3 = ({}) => {
  const { onAction } = useContext(AppContext);
  
  return (
    <form onSubmit={onAction}>
    ...
    </form>
  )
}

这篇关于将React值从子级传递到父级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆