react入个门

起步

react 特点

  • 不使用模板
  • 不是一个mvc框架
  • 响应式
  • 轻量级的js库

原理

  • 虚拟dom 将dom抽象成js对象
  • diff算法

搭建开发环境

react.js 核心文件

react-dom.js 面向web端 渲染页面的dom 依赖于react核心文件

react-native 面向移动端app

babel.js 将es6 转换成es5 jsx转化成javascript

脚手架

npm install -g create-react-app 
create-react-app -version 查看版本
create-react-app [projectName]  //构建项目
npm start //启动

jsx语法

  • js+xml的组合
ReactDOM.render(<h1> hello world </h1>, document.getElementById("root"));
// document.getElementById("root")获取插入的容器
// jsx语法 <h1>hello world</h1>   遇到 <> 按照xml语法解析,遇到{} 按照js 语法解析

元素的渲染

function tick() {
    const element = (  //括号--->需要显示多行标签时使用括号 
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {new Date().toLocaleTimeString()}.</h2>
      </div>
    );
    ReactDOM.render(element, document.getElementById('root'));
  }
  
  setInterval(tick, 1000);

组件

//新建文件封装
import React from "react";
class App extends React.Component {
 render() {
   return ( //多行标签用()
     <div>
       <h1> Hello, world!!!!!!! </h1>
       <h2> It is {new Date().toLocaleTimeString()}. </h2>
     </div>
   );
 }
}

export default App;
 import App from './App'
 ReactDOM.render(<App />, document.getElementById("root"));

props

 //父组件中传入 des字段
 ReactDOM.render(<App des="这是react框架" />, document.getElementById("root"));
//子组件中通过 this.props[字段名]获取数据
class App extends React.Component {
  render() {
    return (
      <div>
        <h1> Hello, world!!!!!!! {this.props.des}</h1>
        <h2> It is {new Date().toLocaleTimeString()}. </h2>
      </div>
    );
  }
}

state

constructor(props) {
    super(props);
    this.state = {  //构造函数中定义state
      count: 10,
    };
  }

  render() {
    return (
      <div>
        <h1> Hello, world!!!!!!! {this.props.des}</h1>
        <h2> It is {this.state.count}. </h2>  //使用state中的变量
      </div>
    );
  }

生命周期

  • componentWillMount:在组件渲染之前使用(beforeMount)
    conponentDidMount:渲染完成(mounted)
    componentUnMount:销毁组件 (beforeDestory)清除定时器等
    
import React from "react";
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 10,
    };
  }
  componentWillMount() {
    console.log("componentWillMount");
  }
  componentDidMount() {
    console.log("componentDidMount");
  }
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }
  shouldComponentUpdate() {
    return true;
  }
  componentWillUpdate() {
    console.log("componentWillUpdate");
  }
  componentDidUpdate() {
    console.log("componentDidUpdate");
  }
  // componentWillReceiveProps() {
  //   console.log("componentWillReceiveProps");
  // }
  addCount = () => {
    console.log(this.state)
    //this.state.count += 1;
    this.setState({
      count: (this.state.count += 1),
    });
  };
  render() {
    return (
      <div>
        <h1> Hello, world!!!!!!! {this.props.des}</h1>
        <h2> It is {this.state.count}. </h2>
        <button onClick={this.addCount}>增加</button>
      </div>
    );
  }
}

export default App;
  • 由上图可知:

    • 单纯渲染组件时 componentWillMount--->componentDidMount

    • 改变state时:shouldComponentUpdate(返回true允许改变,否则不继续运行)---> componentWillUpdate--->componentDidUpdate

    • 由于props是单向传递,当父组件改变props时,触发子组件componentWillReceiveProps函数,

      componentWillReceiveProps-->shouldComponentUpdate(返回true允许改变,否则不继续运行)---> componentWillUpdate--->componentDidUpdate

  • 注:this.state.count += 1;这种直接改变state不会去刷新组件,自然也不会触发生命周期函数,使用setState函数改变state才会重新渲染组件

数据的子传父与父传子

父传子
//父组件
import App from "./App.jsx";
ReactDOM.render(<App des="这是react框架" />, document.getElementById("root"));  //组件中自定义属性
//子组件
//构造器
  constructor(props) {
    super(props);  //super接受props对象
    this.state = {
      count: 10,
    };
  }
  //
    render() {
    return (
      <div>
        <h1> Hello, world!!!!!!! {this.props.des}</h1> 通过this.props调用对应的属性
        <h2> It is {this.state.count}. </h2>
        <button onClick={this.addCount}>增加</button>
      </div>
    );
  }
子传父
  • (利用事件的回传,类似vue中的$emit自定义事件)
//父组件中
  //构造器中定义变量
    constructor() {
    super();
    this.state={
      title:'123'
    }
  }
  //定义所要触发的事件
   changeCount = (data) => {
    this.setState({
      title: data,
    });
  };
  //组件中传递props
    <Mycomponent title={this.state.title} clickChange={this.changeCount}></Mycomponent>
  

子组件可以看到父组件传递的props:

//子组件中
	//定义事件
	addCount = () => {
   	 	this.props.clickChange('子组件传递来的参数');//形参传递给父组件,父组件接收后改变state,然后回传给子组件,子组件重新渲染
  	};
  	//渲染
  render() {
    return (
      <div>       
        <h1> Hello, world!!!!!!! {this.props.title}</h1>
        <button onClick={this.addCount}>增加</button> //传入子组件中定义的事件,然后再触发该事件里面父组件自定义的clickChange事件
      </div>
    );
  }

条件渲染

  //构造器state中定义isLogin变量
  this.state = {
      count: 10,
      isLogin: false,
    };
   //渲染的时候
  changeLogin = () => {
    this.setState({
      isLogin: true,
    });
  };
   render() {
    const { isLogin } = this.state;
    let login = isLogin ? <div>已登陆</div> : <div>未登陆</div>;
    return (
      <div>
        {login} //
        <button onClick={this.changeLogin}>改变登陆状态</button>
      </div>
    );
  }

列表渲染

//state中定义一个数组对象
   userInfo: [
        {
          name: "张三",
          age: 12,
        },
        {
          name: "李四",
          age: 13,
        },
        {
          name: "王五",
          age: 14,
        },
      ],
 
 //render中遍历数组对象进行渲染
    render() {
    return (
      <div>
        <ul>
          {this.state.userInfo.map((el,index) => {
            return (
              <li key={index}>  //注意在最外层添加key,否则会产生警告
                <span>{el.name}</span>
                <span>{el.age}</span>
              </li>
            );
          })}
        </ul>
      </div>
    );
  }

ref

//构造器中创建ref
 constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
//访问ref  通过current属性获取dom对象
this.myRef.current.style.color="red"

受控组件与非受控组件

受控组件
//state动定义
   this.state = {
      value: "",
      value2: "",
      value3: "",
    };
//改变时通过e.target获取值
changeVaue = (e) => {
    this.setState({
      value: e.target.value,
    });
  };
  changeVaue2 = (e) => {
    this.setState({
      value2: e.target.value,
    });
  };
  changeVaue3 = (e) => {
    this.setState({
      value3: e.target.value,
    });
  };
//对input的值进行更新
      <input
          type="text"
          value={this.state.value}
          onChange={this.changeVaue}
        />
        <input
          type="text"
          value={this.state.value2}
          onChange={this.changeVaue2}
        />
        <input
          type="text"
          value={this.state.value3}
          onChange={this.changeVaue3}
        />

非受控组件
  • 当表单的重复工作太多,数据变化的每种方式都编写事件处理函数,比如上面受控组件的情况,这个时候用非受控组件可以很好的解决
  //构造器中创建变量,和ref来操作dom
  this.state = {
      value1: "",
      value2: "",
      value3: "",
    };
    this.myValue1 = React.createRef();
    this.myValue2 = React.createRef();
    this.myValue3 = React.createRef();
//将值与ref节点一一对应
    <input type="text" ref={this.myValue1} />
    <input type="text" ref={this.myValue2} />
    <input type="text" ref={this.myValue3} />
//提交时获取state的值
this.myValue1.current.value //

状态提升

  • 通过一个父组件来管理多个子组件中的数据
//父组件
import React from "react";
import MyComponent from "./component";
import MyForm from "./form";
import Child1 from "./component/child1";
import Child2 from "./component/child2";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      money: 8,

    };
  }
  handleChange = (e) => {
    this.setState({
      money: e.target.value,
    });
  };
  render() {
    return (
      <div>
         <input type="text" value={this.state.money} onChange={this.handleChange} />
        ¥:<Child1 money={this.state.money}></Child1>
        $:<Child2 money={this.state.money}></Child2>
      </div>
    );
  }
}
export default App;

//自组件
import React from "react";
export default class Child1 extends React.Component {
  constructor() {
    super();
 
  }

  render() {
    return (
      <p>{this.props.money }</p>
    );
  }
}

组件的组合

  • 类似vue的slot插槽
//父组件
<Child1 money={this.state.money}>
          <span>组件的组合</span>
</Child1>

//子组件  通过this.props.children调用
<p>
	{this.props.children}
</p>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章