We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
// 推崇原因在于,无状态组件很简单,我们可以将它仅仅作为函数,它的内部并不保存状态 a=> a alway a function Test() { return <h1>tesrt<h1> }
扩展属性是一个JSX特性。这是用于将所有对象的属性作为JSX属性传递的语法糖。 // 写作属性的props <main className="main" role="main">{children}</main> // 从对象中扩展的props <main {...{className: "main", role: "main", children}} /> // 子组件封装以后 我们可以很好地使用这种传递性做render
解构赋值是ES6的新东西 其中要了解的扩展运算符 function Test(props) { return <h1>{props.test}<h1> } function Test({test}) { return <h1>{test}</h1> } const Greeting = ({ name, ...props }) => <div {...props}>Hi {name}!</div> //还可以对值做过滤 const propsThrought = { name: 'kang' } const Greeting = ({ name, ...props }) => <div {...props} {...propsThrought}>Hi {name}!</div>
条件渲染演示
function Test({isRender}) { return isRender ? <h1>render</h1> : <h1>no render</h1> }
children支持多种形式渲染 string <div>string</div> array <div>{[1,2,3,4,5].map(v => <span>v</span>)}</div> // https://codesandbox.io/s/m45p31191y function (需要与父组件协调children的输出) function Text(props) { if (typeof props.children) { return props.children(); } else { return props.children; } } <Text>{() => <div>test</div>}</Text> // https://codesandbox.io/s/72n5jpkp36
<div>{[1,2,3,4,5].map(v => <span>v</span>)}</div> // https://codesandbox.io/s/m45p31191y 子元素是一个元素集合
function (需要与父组件协调children的输出) function Text(props) { if (typeof props.children) { return props.children(); } else { return props.children; } } <Text>{() => <div>test</div>}</Text> // https://codesandbox.io/s/72n5jpkp36
function App() { return ( <div className="App"> <div> <Text>{v => RenderName(v)}</Text> </div> </div> ); } function RenderName({ name }) { return <h1>{name}</h1>; } function Text(props) { if (typeof props.children) { return props.children({ name: "ZWKang" }); } else { return props.children; } } 这种情况的好处是 父元素只充当了数据提供者。 而数据消费者权利交给了callback处理
class SomeContextProvider extends React.Component { getChildContext() { return {some: "context"} } render() { // how best do we return `children`? } } // 此时选择返回子元素的方式 // option 1: 额外的div return <div>{children}</div> // 新版本应该不是问题 // option 2: 无益的错误 return children 作者推荐 最好把子元素当成一种不透明的数据类型。React提供React.Children来适当地处理子元素。 return React.Children.only(this.props.children)
抽象某些组件公共部分形成代理组件 用来省去重复元素属性 <button type="button"> => const Button = props => <button type="button" {...props}> <Button /> // <button type="button"><button> <Button className="CTA">Send Money</Button> // <button type="button" class="CTA">Send Money</button>
将样式分离到各个组件中 如果我们需要这么一个组件 <button type="button" className="btn btn-primary"> => import classnames from 'classnames' const PrimaryBtn = props => <Btn {...props} primary /> const Btn = ({ className, primary, ...props }) => <button type="button" className={classnames( "btn", primary && "btn-primary", className )} {...props} /> PrimaryBtn() ↳ Btn({primary: true}) ↳ Button({className: "btn btn-primary"}, type: "button"}) ↳ '<button type="button" class="btn btn-primary"></button>' 将组件在每层中进行状态的分发,以保证单个状态不至于紊乱。 也方便组合
使用一个函数 对多个事件类型进行处理 handleEvent({type}) { switch(type) { case "click": return require("./actions/doStuff")(/* action dates */) case "mouseenter": return this.setState({ hovered: true }) case "mouseleave": return this.setState({ hovered: false }) default: return console.warn(`No case for event type "${type}"`) } } 在遇到问题之前,不要担心性能优化问题。真的不要。
布局组件会导致某种形式的静态DOM元素。如果有的话,它可能不需要经常更新。 <HorizontalSplit leftSide={<SomeSmartComponent />} rightSide={<AnotherSmartComponent />} /> 虽然 HorizontalSplit 将成为这两个组件的父组件,但它永远不会是他们的所有者。我们可以告诉它永远不更新,而不会中断组件的生命周期。 (只是当前的HorizontalSplit 不会rerender 但是子组件的re render还会继续) class HorizontalSplit extends React.Component { shouldComponentUpdate() { return false } render() { <FlexContainer> <div>{this.props.leftSide}</div> <div>{this.props.rightSide}</div> </FlexContainer> } }
我们一般让处理数据 与数据状态打交道的上层组件称为容器组件 他一般是接纳无状态组件 也就是展示型组件直接render,也就是控制点移交一处 const CommentList = ({ comments }) => <ul> {comments.map(comment => <li>{comment.body}-{comment.author}</li> )} </ul> class CommentListContainer extends React.Component { constructor() { super() this.state = { comments: [] } } componentDidMount() { $.ajax({ url: "/my-comments.json", dataType: 'json', success: comments => this.setState({comments: comments}); // 数据获取 }) } render() { return <CommentList comments={this.state.comments} /> //render数据 } }
高阶组件一般是存储一些可复用逻辑,可复用类型。 我们可以直接patch到组件内。 不过还是还注意静态方法的传递,props名字的重复,高阶组件的传递,样板代码过多。 const Greeting = ({ name }) => { if (!name) { return <div>Connecting...</div> } return <div>Hi {name}!</div> } const Connect = ComposedComponent => class extends React.Component { constructor() { super() this.state = { name: "" } } componentDidMount() { // this would fetch or connect to a store this.setState({ name: "Michael" }) } render() { return ( <ComposedComponent {...this.props} name={this.state.name} /> ) } } const ConnectedMyComponent = Connect(Greeting)
这是为任何数量的无状态函数组件提供获取和绑定数据的强大模式。
class NameContainer extends React.Component { render() { return <Name onChange={newName => alert(newName)} /> } } const Name = ({ onChange }) => <input onChange={e => onChange(e.target.value)} /> class NameContainer extends React.Component { constructor() { super() this.state = {name: ""} } render() { return <Name onChange={newName => this.setState({name: newName})} /> } }
受控组件常常是需要一个state来维护表单字段数据
而非受控组件常常是直接通过取得ref input元素的值进行处理
The text was updated successfully, but these errors were encountered:
No branches or pull requests
条件渲染演示
这是为任何数量的无状态函数组件提供获取和绑定数据的强大模式。
子组件可以通过父组件传递的callback 去影响父组件状态
受控组件常常是需要一个state来维护表单字段数据
而非受控组件常常是直接通过取得ref input元素的值进行处理
link
The text was updated successfully, but these errors were encountered: