一小時入門React

wxz在掘金發表於2019-10-30

1.基本語法(jsx)

const name="小明";
const getName = () => {
    return "小明"
}
const element = <h1>Hello, world!</h1>;
// 嵌入變數
const element = <h1>Hello, {name}</h1>;
// 嵌入表示式
const element = <h1>Hello, {getName()}</h1>;
複製程式碼

注意:在點選事件中,不要直接呼叫函式,如果需要傳遞引數,使用箭頭函式,jsx中所有dom事件必須用駝峰命名。如下:

const a = <a onClick={() => this.handleClick(params)}>點選</a>
複製程式碼

1.1. 條件渲染

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}
複製程式碼

1.2. 迴圈渲染

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);
複製程式碼

2.元件

react中所有的東西都是元件,從定義型別元件分為函式式元件class元件兩種,從功能上區分又有容器組件和ui元件,根據表單相關又可以分為受控元件非受控元件,更高階的元件用法還有高階元件等。

react時單向資料流,資料只能從父元件傳遞給子元件,子元件通過props引數獲取父元件傳遞的內容。

2.1.函式式元件

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
複製程式碼

2.2.class元件

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
複製程式碼

2.3.容器元件

負責處理業務邏輯

//容器元件
class TodoListContainer extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            todos:[]
        }
        this.fetchData = this.fetchData.bind(this);
    }
    componentDidMount(){
        this.fetchData();
    }
    fetchData(){
        fetch('/api/todos').then(data =>{
            this.setState({
                todos:data
            })
        })
    }
    render(){
        return (
            <div>
                <TodoList todos={this.state.todos} />    
            </div>
        )
    }
}
複製程式碼

2.4.UI元件

只負責展示

//展示元件
class TodoList extends React.Component{
    constructor(props){
        super(props);
    }
    render(){
        const {todos} = this.props;
        return (
            <div>
                <ul>
                    {todos.map((item,index)=>{
                        return <li key={item.id}>{item.name}</li>
                    })}
                </ul>
            </div>
        )
    }
複製程式碼

2.5.受控元件

React 的 state 為“唯一資料來源”。渲染表單的 React 元件還控制著使用者輸入過程中表單發生的操作。被 React 以這種方式控制取值的表單輸入元素就叫做“受控元件”。

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('提交的名字: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          名字:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="提交" />
      </form>
    );
  }
}
複製程式碼

2.6.非受控元件

表單資料將交由 DOM 節點來處理

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
複製程式碼

2.7.高階元件

高階元件主要用來處理元件直接按可複用的邏輯,將可複用的部分抽離出來,供其餘元件使用。

高階元件是引數為元件,返回值為新元件的函式

const EnhancedComponent = higherOrderComponent(WrappedComponent);
複製程式碼

詳情請參考react官網 高階元件教程

3.元件生命週期

3.1.掛載

當元件例項被建立並插入 DOM 中時,其生命週期呼叫順序如下:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount() ---通常在此生命週期獲取後端資料

3.2.更新

當元件的 props 或 state 發生變化時會觸發更新。元件更新的生命週期呼叫順序如下:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate() ---常用於程式碼優化
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

3.3.圖解

一小時入門React

4.setState詳解

setState() 將對元件 state 的更改排入佇列,並通知 React 需要使用更新後的 state 重新渲染此元件及其子元件。這是用於更新使用者介面以響應事件處理器和處理伺服器資料的主要方式。

4.1. 基本用法和引數

setState有兩個引數,第一個是要更新的內容,可以是物件或者函式,第二個引數是回撥函式更新完成後的操作可以寫在回撥函式中。

1)第一引數為物件

this.setState({quantity: 2})
複製程式碼

2)第一引數為函式

this.setState((state, props) => {
  return {counter: state.counter + props.step};
});
複製程式碼

setState() 的第二個引數為可選的回撥函式,它將在 setState 完成合並並重新渲染元件後執行。通常,我們建議使用 componentDidUpdate() 來代替此方式。

4.2 setState()執行後發生了什麼?

  • static getDerivedStateFromProps()
  • shouldComponentUpdate() ---返回true則繼續往下執行,返回false將不繼續執行
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

5.路由基礎

react-router官網

react路由升級到v4版本之後(目前已經到v5),路由直接整合到DOM結構中,最常用的路由元件有:

 // 相當於a標籤的功能
 <Link to="/">Home</Link>
 
 // 路由容器,傳入元件後,匹配到路由就會渲染對應元件
 <Route exact path="/" component={Home} />
 <Redirect to="/somewhere/else" />
 
 // 單頁應用路由元件要包含整個專案最大的容器
 <Router>
  <App />
 </Router>
 
 // 使用switch將Route或者Redirect包起來之後,智慧渲染第一個匹配路由的元件
 <Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/:user" component={User}/>
  <Route component={NoMatch}/>
 </Switch>

複製程式碼

關於每個路與元件詳細的api介紹,請參考react-router官網

  1. React周邊

相關文章