react组件---组件间通讯

1、父组件向子组件通讯

React 数据流动是单向的,父组件向子组件的 通讯也是最多见的方式。父组件经过 props 向子组件传递须要的信息html

function EmailInput(props) {
  return (
    <label>
      Email: <input value={props.email} />
    </label>
  );
}

const element = <EmailInput email="123124132@163.com" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

2、子组件向父组件通讯

回调函数

function EmailInput(props) {
  return (
    <label>
      Email: <input value={props.email} onChange={props.onChangeEmail} />
    </label>
  );
}

class App extends React.Component{
   constructor(props){
     super(props);
     this.state = {
       email: ''
     }
   }
   onChangeEmail(e) => {
     console.log(e.target.value)
     this.setState({
       email: e.target.value
     });
   }
   render(){
     let { email } = this.state;
     return (
       <EmailInput email={ eamil } onChangeEmail={this.onChangeEmail} />;
     )
   }
}

ReactDOM.render(
  <APP />,
  document.getElementById('root')
);

3、跨级组件通讯Context

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言react

不使用Context的状况

class App extends React.Component {
  render() {
    return <Toolbar theme="dark" />;
  }
}

function Toolbar(props) {
  // Toolbar 组件接受一个额外的“theme”属性,而后传递给 ThemedButton 组件。
  // 若是应用中每个单独的按钮都须要知道 theme 的值,这会是件很麻烦的事,
  // 由于必须将这个值层层传递全部组件。
  return (
    <div>
      <ThemedButton theme={props.theme} />
    </div>
  );
}

class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}

使用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} />;
  }
}

Context 主要应用场景在于不少不一样层级的组件须要访问一样一些的数据。请谨慎使用,由于这会使得组件的复用性变差。使用 context 比较好的场景是真正意义上的全局信息且不会更改,例如界面主题、用户信息等
若是你只是想避免层层传递一些属性,组件组合(component composition)有时候是一个比 context 更好的解决方案ide

props层层传递user和avatarSize

<Page user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>

将Avatar组件自身向下传递

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

// 如今,咱们有这样的组件:
<Page user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<PageLayout userLink={...} />
// ... 渲染出 ...
<NavigationBar userLink={...} />
// ... 渲染出 ...
{props.userLink}

这种对组件组合减小了在你的应用中要传递的 props 数量,这在不少场景下会使得你的代码更加干净,使你对根组件有更多的把控。可是,这并不适用于每个场景:这种将逻辑提高到组件树的更高层次来处理,会使得这些高层组件变得更复杂,而且会强行将低层组件适应这样的形式,这可能不会是你想要的函数

并且你的组件并不限制于接收单个子组件。你可能会传递多个子组件,甚至会为这些子组件(children)封装多个单独的“接口(slots)”,React 元素本质就是对象(object),因此你能够把它们看成 props,像其余数据同样传递。这种方法可能使你想起别的库中“槽”(slot)的概念,但在 React 中没有“槽”这一律念的限制,你能够将任何东西做为 props 进行传递。this

function Page(props) {
  const user = props.user;
  const content = <Feed user={user} />;
  const topBar = (
    <NavigationBar>
      <Link href={user.permalink}>
        <Avatar user={user} size={props.avatarSize} />
      </Link>
    </NavigationBar>
  );
  return (
    <PageLayout
      topBar={topBar}
      content={content}
    />
  );
}
相关文章
相关标签/搜索