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>

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