这个也是教程里的小栗子:
需求描述
界面包括两部分:
显示部分:如果用户未登录,显示Please Login In;如果用户已登录,显示Welcome back Mister;
按钮部分:如果用户未登录,按钮显示Login In;如果用户已登录,显示Login Out;
按钮功能:如果用户未登录,按钮按下进入登录的样式;如果用户已登录,按下按钮进入未登录的样式;
逻辑分析
- 整个界面作为一个最大的组件,组件包括两个小组件:文字<GreatingMsg/>和按钮<GreatingButton/>
- App组件包括一个状态isLoginIn,枚举true或者false。
- <GreatingMsg/>和<GreatingButton/>两个组件都需要知道App组件的状态。为了保持组件间的通信,将state.isLoginIn绑定到props.isLoginIn上,即调用子组件的时候,加上isLoginIn={this.state.isLoginIn}。子组件通过判断props里的isLoginIn值来显示不同内容。
- App组件需要增加一个能取反自己state.isLoginIn值的方法。<GreatingButton/>能在onClick事件里调用该方法。达到按钮功能。为了能把App里的方法传出去,<GreatingButton/>必须开放一个API:props.handleClick,App调用<GreatingButton/>的时候增加一个handleClick的props,把自己的切换的方法传进去。
代码部分
import React from 'react';
import ReactDOM from 'react-dom';
const GreatingMsg = (props) => {
return(
(props.isLoginIn) ?
<h2>Welcome back Mister</h2> :
<h2>Please Login In</h2>
);
}
/*const GreatingButton = (props) => {
return(
(props.isLoginIn) ? <ButtonLoginOut/> : <ButtonLoginIn/>
);
}*/
const ButtonLoginIn = (props) => {
return(
<button onClick={props.handleClick}>Login In</button>
);
}
const ButtonLoginOut = (props) => {
return(
<button onClick={props.handleClick}>Login Out</button>
);
}
class LoginControl extends React.Component {
constructor(props){
super(props);
this.state={isLoginIn:false};
};
handleClick(){
this.setState( (preState) => ({isLoginIn:!preState.isLoginIn}) );
};
render() {
const isLoginIn = this.state.isLoginIn;
// const buttonMsg = (this.state.isLoginIn) ? 'Login In' : 'Login Out' ;
const GreatingButton = (this.state.isLoginIn)
? <ButtonLoginOut handleClick={this.handleClick.bind(this)}/>
: <ButtonLoginIn handleClick={this.handleClick.bind(this)}/> ;
return (
<div>
<GreatingMsg isLoginIn={isLoginIn}/>
{/*<GreatingButton isLoginIn={isLoginIn} handleClick={this.handleClick.bind(this)}/>*/}
{/*<ButtonLoginIn handleClick={this.handleClick.bind(this)}/>*/}
{GreatingButton}
{/*<button onClick={this.handleClick.bind(this)}>{buttonMsg}</button>*/}
</div>
);
}
}
ReactDOM.render(
<LoginControl/>,
document.getElementById('container')
);
总结
- 整体逻辑很简单,写的时候感觉如果上来就拆分组件出错的概率比较高。文字部分没什么难度我就直接先拆分出来了。按钮部分我先在App组件里实现好了然后再分离开的。这样感觉调试起来会比较快,不容易直接卡死。
- 拆分组件的方法见仁见智吧,目前的思路就是让App的部分看上去越简单越好,逻辑放在子组件里。如果子组件逻辑也复杂了再继续拆分。
- 组件通信主要是API的思维,谁需要什么,谁能有什么,然后通过props对外接就好了。