4.4 KiB
4.4 KiB
id | title | challengeType | isRequired | videoUrl | localeTitle |
---|---|---|---|---|---|
5a24c314108439a4d403617a | Pass State as Props to Child Components | 6 | false | 将状态作为道具传递给子组件 |
Description
state
,然后呈现子组件。您希望这些组件可以访问该state
某些部分,这些部分作为props传递。例如,您可能有一个App
组件可以呈现Navbar
以及其他组件。在您的App
,您的state
包含大量用户信息,但Navbar
只需要访问用户的用户名,以便显示它。您将该state
作为prop传递给Navbar
组件。这种模式说明了React中的一些重要范例。第一种是单向数据流 。状态沿着应用程序组件树的一个方向流动,从有状态父组件到子组件。子组件仅接收所需的状态数据。第二,复杂的有状态应用程序可以分解为几个或者一个有状态的组件。其余组件只是从父级接收状态作为props,并从该状态呈现UI。它开始创建一个分离,其中状态管理在代码的一部分中处理,而UI在另一部分中呈现。将状态逻辑与UI逻辑分离的原则是React的关键原则之一。当它被正确使用时,它使复杂的有状态应用程序的设计更容易管理。 Instructions
MyApp
组件是有状态的,并将Navbar
组件呈现为子组件。将name
属性的state
向下传递给子组件,然后在h1
标记中显示该name
,该name
是Navbar
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