freeCodeCamp/curriculum/challenges/chinese/03-front-end-libraries/react/pass-state-as-props-to-chil...

4.4 KiB
Raw Blame History

id title challengeType isRequired videoUrl localeTitle
5a24c314108439a4d403617a Pass State as Props to Child Components 6 false 将状态作为道具传递给子组件

Description

您看到了许多在先前的挑战中将道具传递给子JSX元素和子React组件的示例。您可能想知道这些道具来自哪里。一种常见的模式是让一个有状态的组件包含对您的应用程序很重要的state ,然后呈现子组件。您希望这些组件可以访问该state某些部分这些部分作为props传递。例如您可能有一个App组件可以呈现Navbar以及其他组件。在您的App ,您的state包含大量用户信息,但Navbar只需要访问用户的用户名,以便显示它。您将该state作为prop传递给Navbar组件。这种模式说明了React中的一些重要范例。第一种是单向数据流 。状态沿着应用程序组件树的一个方向流动从有状态父组件到子组件。子组件仅接收所需的状态数据。第二复杂的有状态应用程序可以分解为几个或者一个有状态的组件。其余组件只是从父级接收状态作为props并从该状态呈现UI。它开始创建一个分离其中状态管理在代码的一部分中处理而UI在另一部分中呈现。将状态逻辑与UI逻辑分离的原则是React的关键原则之一。当它被正确使用时它使复杂的有状态应用程序的设计更容易管理。

Instructions

MyApp组件是有状态的,并将Navbar组件呈现为子组件。将name属性的state向下传递给子组件,然后在h1标记中显示该name ,该nameNavbar render方法的一部分。

Tests

tests:
  - text: <code>MyApp</code>组件应该使用内部的<code>Navbar</code>组件进行渲染。
    testString: 'assert((function() { const mockedComponent = Enzyme.mount(React.createElement(MyApp)); return mockedComponent.find("MyApp").length === 1 && mockedComponent.find("Navbar").length === 1; })(), "The <code>MyApp</code> component should render with a <code>Navbar</code> component inside.");'
  - text: <code>Navbar</code>组件应该将<code>MyApp</code>状态属性<code>name</code>作为props接收。
    testString: 'async () => { const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250)); const mockedComponent = Enzyme.mount(React.createElement(MyApp)); const setState = () => { mockedComponent.setState({name: "TestName"}); return waitForIt(() => mockedComponent.find("Navbar").props() )}; const navProps = await setState(); assert(navProps.name === "TestName", "The <code>Navbar</code> component should receive the <code>MyApp</code> state property <code>name</code> as props."); }; '
  - text: <code>Navbar</code>的<code>h1</code>元素应该呈现<code>name</code> prop。
    testString: 'async () => { const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250)); const mockedComponent = Enzyme.mount(React.createElement(MyApp)); const navH1Before = mockedComponent.find("Navbar").find("h1").text(); const setState = () => { mockedComponent.setState({name: "TestName"}); return waitForIt(() => mockedComponent.find("Navbar").find("h1").text() )}; const navH1After = await setState(); assert(new RegExp("TestName").test(navH1After) && navH1After !== navH1Before, "The <code>h1</code> element in <code>Navbar</code> should render the <code>name</code> prop."); }; '

Challenge Seed

class MyApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'CamperBot'
    }
  }
  render() {
    return (
       <div>
         <Navbar /* your code here */ />
       </div>
    );
  }
};

class Navbar extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
    <div>
      <h1>Hello, my name is: /* your code here */ </h1>
    </div>
    );
  }
};

After Test

console.info('after the test');

Solution

// solution required