工作原因,现在需要学react,每天记录一点学习心得
组件化思想
react把页面划分为一个个组件,也就是,一个页面是由一个个组件组成的,比如button,就是一个按钮组件。
组件的创建
第一种方式
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
第二种方式
class hs2 extends React.Component{
render(){
return <h1>组件测试2</h1>
}
}
使用演示全部代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>react组件</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="tt2"></div>
<script type="text/babel">
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="test" />;
ReactDOM.render(
element,
document.getElementById('tt2')
);
</script>
</body>
</html>
运行:
注意:组件名内不能直接使用style,但是视图层可以,所以可以把style定义在视图层而不是,组件名内。 如果我们需要向组件传递参数,可以使用this.props对象 直接用上面这个代码 注意:在添加属性时,class属性要写成className属性,for属性要写成htmlFor,因为class和for是JavaScript的保留字、
复合组件
复合组件就是把不用的组件合成一个组件,这样做可以把组件的不同功能点分离 示例
function Name(props){
return <h1> 名字 {props.name}</h1>;
}
function Url(props){
return <h1> 住址{props.url}</h1>;
}
function Pickname(props){
return <h1> 小名 {props.picknae}</h1>;
}
function App(){
return(
<div>
<Name name="喜洋洋"/>
<Url url="https://github.com/marktext/marktext"/>
<Pickname pickname="喜羊羊"/>
</div>
)
}
ReactDOM.render(
<App/>,
document.getElementById('tt2')
)
运行
props
一个组件可以接受外界的props,组件自身相当于一个函数,props可以作为一个参数传递 ,旨在将任意数据传给组件。 下面是示例,state定义的是props的默认值,当组件没有name的时候,就会采用默认值 注意,组件的命名一定要符合大驼峰命名方式,也就是首字母大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>组件</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Sayname extends React.Component{
static defaultProps={
name:'props 的默认值'
}
render(){
return(
<h1>hello{this.props.name}</h1>
);
}
}
ReactDOM.render(
<Sayname name="123" />,
document.getElementById('root'));
</script>
</body>
</html>
state
state是状态,可以把组件理解为一个状态机,state就是来记录它的状态的 state跟props比起来,是可以修改的,它的基本操作有初始化,读取,更新 示例 代码解释:下面这个代码里面,isred就是这个组件state,通过绑定方法,handleClick,利用setstate 来改变isred的值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class ChangeColor extends React.Component{
constructor(props){
super(props);
this.state={isRed:true};
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
this.setState((prevState,props)=>({
isRed:!prevState.isRed
}))
}
render() {
var redStyle={
color:"red"
}
var blueStyle={
color:"blue"
}
return (
<div>
<h1 style={this.state.isRed ? redStyle:blueStyle}>123</h1>
<button onClick={this.handleClick}>点击改变颜色</button>
</div>
);
}}
ReactDOM.render(
<ChangeColor />,
document.getElementById('root')
);
</script>
</body>
</html>
setstate方法有两个参数,官方给出了说明,第一个是要改变的state对象,第二个是回调函数
void setstate(
function|object nextState,
[function callback]
)
组件之间的通信
组件之间,避免不了通信,那么首先要对react之间的两种数据方式进行了解 ,也就是state和props,props 是传递给组件的(类似于函数的形参),而 state 是在组件内被组件自己管理的
父子组件通信
在react中,数据流是单向的
通过props节点从父组件到子组件,如果父组件的props发生改变,则react会遍历整颗组件树,从而渲染到这个 props的所有组件 父组件更新子组件,可以直接通过props进行消息传递实现更新操作。
父组件更新子组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>父子组件通信</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Child extends React.Component{
constructor(props){
super(props);
this.state = {}
}
render(){
return (
<div>
{this.props.text}
</div>
)
}
}
class Father extends React.Component{
constructor(props){
super(props);
this.state = {}
}
refreshChild(){
return (e)=>{
this.setState({
childText: "父组件更新子组件成功",
})
}
}
render(){
return (
<div>
<button onClick={this.refreshChild()} >
父组件更新子组件
</button>
<Child text={this.state.childText || "子组件更新前"} />
</div>
)
}
}
ReactDOM.render(<Father />, document.getElementById('root'));
</script>
</body>
</html>
子组件更新父组件
子组件更新父组件,需要父组件传一个回调函数给子组件调用,就可以触发父组件更新了 通过绑定refreshParent,用setstate对父组件的state进行修改
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Child extends React.Component{
constructor(props){
super(props);
this.state = {}
}
render(){
return (
<div>
<button onClick={this.props.refreshParent}>
更新父组件
</button>
</div>
)
}
}
class Father extends React.Component{
constructor(props){
super(props);
this.state = {}
}
refreshParent(){
this.setState({
parentText:"子组件更新父组件成功"
})
}
render(){
return (
<div>
<Child refreshParent={this.refreshParent.bind(this)}></Child>
{this.state.parentText || "父组件更新前"}
</div>
)
}
}
ReactDOM.render(<Father />, document.getElementById('root'));
</script>
</body>
</html>
运行
同级组件进行通信
所谓同级组件,有两种情况: 第一种:这两个组件是由同一个父组件,即一个子组件可以通过父组件的回调函数来改变props,从而改变 另一个子组件的props。 第二种:两个组件由相同的祖先,但不一定是亲兄弟,但是如果是这样 的话,父组件一级一级去访问,效率会很差,React提供了一种上下文方式 允许子组件直接访问祖先组件的属性和方法,,从而使得效率大大的提升。
兄弟组件通信
代码解释: 两个组件Borther1和Borther2有共同的父组件,Father组件,组件一通过refresh 调用setState方法,修改兄弟组件的state,从而达到了通信的目的
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Borther1 extends React.Component{
constructor(props){
super(props);
this.state={}
}
render(){
return(
<div>
<button onClick={this.props.refresh}>
更新兄弟组件
</button>
</div>
);
}
}
class Borther2 extends React.Component{
constructor(props){
super(props);
this.state={}
}
render(){
return(
<div>
{this.props.text || "兄弟组件未更新"}
</div>
);
}
}
class Father extends React.Component{
constructor(props){
super(props);
this.state={}
}
refresh(){
return (e)=>{
this.setState({
text:"兄弟组件更新成功"
})
}
}
render(){
return(
<div>
<h2>兄弟组件更新</h2>
<Borther1 refresh={this.refresh()}/>
<Borther2 text={this.state.text}/>
</div>
);
}
}
ReactDOM.render(
<Father />,
document.getElementById('root')
);
</script>
</body>
</html>
运行 点击更新兄弟组件
生命周期函数
生命周期,很显然的意思,生命的周期,从出生到消亡的整个过程。 react的生命周期有三个阶段: 挂载期:一个组件初次被创建的过程 更新期:组件在创建后再次被渲染的过程 卸载期:组件在使用完被销毁的过程
挂载期
组件在创建后,第一次的渲染被称为挂载期,挂载期有一些方法会被 一次调用: constructor(构造函数,初始化状态值) getInitialState(设置状态机) getDefaultProps(获取默认的props) componentWillMount(首次渲染前执行) render(渲染组件) componentDidMount(render渲染后执行的操作) 代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class HelloWorld extends React.Component{
constructor(props){
super(props);
console.log("1.构造函数")
this.state={}
console.log("2.设置状态机")
}
componentWillMount(){
console.log("3.完成首次渲染")
}
render(){
console.log("4.组件进行渲染")
return(
<div>
<div>{this.props.name}</div>
</div>
);
}
componentDidMount(){
console.log("5.componentDidMount render渲染后的操作")
}
}
ReactDOM.render(
<HelloWorld />,
document.getElementById('root')
);
</script>
</body>
</html>
运行并查看控制台: 发现,在组件创建的时期会以此执行上述函数,我们目前在这个挂载期已经实现了,设置state的初始值在构造函数中以this.state来处理,获取来处理,获取props用defaultprops来获取,在react组件中render方法必须实现,如果没有实现会报错,其他的方法不必须规定实现,因为,其他的方法在父类Component都有默认实现。
更新期
组件更新,指的是在组件初次渲染之后,进行了组件状态的改变。 组件更新包括的方法: componentWillReveiceProps:当父组件更新子组件的state时,该方法会被调用
shouldComponentUpdate:该方法决定组件state或者props的改变是否需要重新渲染组件、
componentWillUpdate:在组件接受新的props或者state时, 即将进行重新渲染前调用该方法。
componentDidUpdate:在组件重新渲染后调用该方法。 代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class HelloWorldFather extends React.Component{
constructor(props) {
super(props);
this.updateChildProps = this.updateChildProps.bind(this);
this.state = {
name:"这里是父组件"
}
}
updateChildProps(){
this.setState({
name:"子组件更新的内容123"
})
}
render(){
return(
<div>
<HelloWorld name={this.state.name}></HelloWorld>
<button onClick={this.updateChildProps}>更新子组件props</button>
</div>
)
}
}
class HelloWorld extends React.Component {
constructor(props) {
super(props);
console.log("1. 构造函数")
console.log("2. 设置状态机")
}
componentWillMount(){
console.log('3. componentWillMout 完成首次渲染前调用')
}
componentWillReceiveProps(){
console.log("6. 父组件更新子组件props时,调用该方法")
}
shouldComponentUpdate(){
console.log("7. 决定组件props或者state的改变是否需要进行重新渲染")
return true;
}
componentWillUpdate(){
console.log("8. 当接收到新的props或state时,调用该方法")
}
render () {
console.log('4. 组件进行渲染');
return(
<div>
<div>{this.props.name}</div>
</div>
)
}
componentDidMount() {
console.log('5. componentDidMount render渲染后的操作' )
}
componentDidUpdate(){
console.log("9. 组件重新被渲染后,调用该方法")
}
}
ReactDOM.render(<HelloWorldFather />, document.getElementById('root'));
</script>
</body>
</html>
运行: 此时是页面首次渲染 点击更新子组件之后
卸载期
生命周期最后一个阶段称为卸载期,也称为组件销毁期 主要涉及的生命周期函数是: componentWillUnmount:当组件从Dom树删除时调用该方法。
|