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}
    />
  );
}
相關文章
相關標籤/搜索