美文网首页
react 父子组件

react 父子组件

作者: 海豚先生的博客 | 来源:发表于2020-05-02 12:15 被阅读0次

父子组件传值

使用props

class App extends React.Component{
  render () {
    return (
     <div>
      <Toolbar theme="dark" />
     </div>
    )
}
function Toolbar(props) {
  return (
    <div>
      <ThemedButton theme={props.theme} />
    </div>
  );
}
class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}

使用context

  • Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。请谨慎使用,因为这会使得组件的复用性变差。
// Context 可以让我们不必经过每层组件传递,就能将值直达目标组件。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
    // 无论多深,任何组件都能读取这个值。
    // 在这个例子中,我们将 “dark” 作为当前的值传递下去。
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 指定 contextType 读取当前的 theme context。
  // React 会往上找到最近的 theme Provider,然后使用它的值。
  // 在这个例子中,当前的 theme 值为 “dark”。
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
}

#组件不在一个文件中,怎么获取ThemeContext ?

在消费组件中更新context

ThemeContext.Provider组件是包裹消费组件的,消费组件中是个函数

<ThemeContext.Consumer>
      {({theme, toggleTheme}) => (
        <button          onClick={toggleTheme}
          style={{backgroundColor: theme.background}}>

          Toggle Theme
        </button>
        <OtherComponent></OtherComponent>
      )}
    </ThemeContext.Consumer>

父组件导出ThemeContext,子组件中引入ThemeContext即可

如果只有嵌套最深那个组件需要(中间层组件不需要)顶层组件的某些值,可以将嵌套最深的那个组件传递下去

function Page(props) {
  const user = props.user;
  const userLink = (
    <Link href={user.permalink}>
      <Avatar user={user} size={props.avatarSize} />
    </Link>
  );
  return <PageLayout userLink={userLink} />;
}

// 现在,我们有这样的组件:也是一级一级传递userLink,但是传递的属性数量变少了,因为userLink是一个组件
<Page user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<PageLayout userLink={...} />
// ... 渲染出 ...
<NavigationBar userLink={...} />
// ... 渲染出 ...
{props.userLink}
// 也可以传递多个组件
<NavigationBar userLink={...} content={...} />
渲染
<div>{this.props.userLink}</div>
<div>{this.props.content}</div>

这并不适用于每一个场景:这种将逻辑提升到组件树的更高层次来处理,会使得这些高层组件变得更复杂,并且会强行将低层组件适应这样的形式,这可能不会是你想要的。

父子组件修改对方的state

父组件使用ref修改子组件的state

父组件
<Child ref="c1" />
在事件中调用子组件方法this.refs.c1.add()
子组件
add () { this.setState({num: this.state.num + 1})

子组件使用ref修改父组件state

父组件
add () { this.setState({num: this.state.num + 1})
<Child par={this} />
子组件
this.props.par.add()
官方文档ref的使用方式
// 必须使用React.forwardRef进行转发
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));

// 你可以直接获取 DOM button 的 ref:
handleClick () {
console.log(this.ref.current) // 得到button 元素
this.ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

this.props.children

组件标签内部所有元素

// 父组件
<Com >
  <div>hello world </div>
  <p>ppp</p>
</Com>
// 子组件
<div> { this.props.children } </div>
// 也可以遍历子组件,如果有2个,react就生成一个array,此外还有forEach,count方法
<div> { React.Children.map(this.props.children, child => <div>{child}</div>) } </div>

父组件获取子组件的值

  • 父组件可以传递给子组件一个回调函数获取子组件的某些数值
父组件
onChange={ this.fn.bind(this) }
fn=(selected) => {  }
子组件
this.props.onChange(arr)
  • 子组件保存属性到this上,父组件通过ref获取
子组件
this.arrChecked = [ ]
父组件取
this.refs.tab1.arrChecked

父组件传递参数组件,子组件预留位置

// 父组件
function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}
// 子组件
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

相关文章

网友评论

      本文标题:react 父子组件

      本文链接:https://www.haomeiwen.com/subject/diohghtx.html