React Basic

学习一下前端知识来完成基本的项目。。

环境准备

  • 安装node,配置环境变量
  • 安装react脚手架 npm install -g create-react-app

目录结构:

r0

组件

前端组件化,将复杂前端分割成多个组件完成

r1

在index.js中

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

serviceWorker用于离线保存网页

其中引入了app组件

ReactDOM.render(, document.getElementById(‘root’));

在app.js中定义组件

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

r2

编写简单的组件:Rex.js

import React, { Component} from "react";

class Rex extends Component{
    render() {
        return(
            <div>
                hello rex
            </div>
        );
    }
}

export default Rex;

index.js中改变引用(组件的开头必须大写)

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import App from './App';
import Rex from './Rex';
import * as serviceWorker from './serviceWorker';

// ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(<Rex />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

显示效果:

r3

JSX

必须引入react,才可以使用JSX语法,是一种在js中使用html的方式

大写标签代表组件,小写标签代表html

react中,component render返回的html,最外层必须被包裹

import React , { Component, Fragment} from 'react';

class TodoList extends Component{
    render() {
        return(

            <Fragment>
                <div>
                    <input/>
                    <button>submit</button>
                </div>

                <ul>
                    <li>hahah</li>
                </ul>
            </Fragment>

        )
    }
}
export default TodoList;

Fragment为最外层隐形div(大写开头为组件)

JSX注释{/ /}

创建css文件

.input {
    border: 1px solid red;
}

导入包

impott ‘./xxx.css’;

<input
    className-'input'
    />

触发光标位置

<label htmlFor="id">label</label>

响应式与事件

react中的类默认一个构造函数,会率先触发,state负责存储数据

react可以给页面状态,响应状态的变化

import React , { Component, Fragment} from 'react';

class TodoList extends Component{

    constructor(props) {
        super(props);
        this.state = {
            input: '',
            list: []
        }
    }


    render() {
        return(

            <Fragment>
                <div>
                    <input
                        value={this.state.input}
                        onChange={this.handleInputChange.bind(this)}
                    />
                    <button>submit</button>
                </div>

                <ul>
                    <li>hahah</li>
                </ul>
            </Fragment>

        )
    }

    handleInputChange(e){
        this.setState({
            input: e.target.value
        })
    }

}
export default TodoList;

绑定相同this,通过e传递数据,并通过setState改变数值,全程对数据操作

实现一个TodoList

react不允许对state进行操作,必须深拷贝操作,以方便优化性能

import React , { Component, Fragment} from 'react';

class TodoList extends Component{

    constructor(props) {
        super(props);
        this.state = {
            input: '',
            list: []
        }
    }

    render() {
        return(
            <Fragment>
                <div>
                    <input
                        value={this.state.input}
                        onChange={this.handleInputChange.bind(this)}
                    />
                    <button
                        onClick={this.handleBtnClick.bind(this)}
                    >Submit</button>
                </div>
                <ul>
                        {
                            this.state.list.map((item,index) =>{
                                return<li
                                    key={index}
                                    onClick={this.handleDelete.bind(this,index)}
                                >{item}</li>
                            })
                        }
                </ul>
            </Fragment>
        )
    }

    handleBtnClick(){
        this.setState({
            list: [...this.state.list, this.state.input],
            input: ''
        })
    }

    handleInputChange(e){
        this.setState({
            input: e.target.value
        })
    }

    handleDelete(index){
        const list = [...this.state.list];
        list.splice(index,1);
        this.setState({
            list: list
        })
    }

}
export default TodoList;

r4

组件.js之间的传值

大组件:

import React, { Component, Fragment } from 'react';
import TodoItem from './TodoItem';
import Test from './Test';
import './style.css';

class TodoList extends Component {

    constructor(props) {
        super(props);
        // 当组件的state或者props发生改变的时候,render函数就会重新执行
        this.state = {
            inputValue: '',
            list: []
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleBtnClick = this.handleBtnClick.bind(this);
        this.handleItemDelete = this.handleItemDelete.bind(this);
    }

    render() {
        return (
            <Fragment>
                <div>
                    <label htmlFor="insertArea">输入内容</label>
                    <input 
                        id="insertArea"
                        className='input'
                        value={this.state.inputValue}
                        onChange={this.handleInputChange}
                    />
                    <button onClick={this.handleBtnClick}>提交</button>
                </div>
                <ul>
                    {this.getTodoItem()}
                </ul>
                <Test content={this.state.inputValue}/>
            </Fragment>
        )
    }

    getTodoItem() {
        return this.state.list.map((item, index) => {
            return (
                <TodoItem 
                    key={index}
                    content={item} 
                    index={index}
                    deleteItem={this.handleItemDelete}
                />
            )
        })
    }

    handleInputChange(e) {
        const value = e.target.value;
        this.setState(() => ({
            inputValue: value
        }));
    }

    handleBtnClick() {
        this.setState((prevState) => ({
            list: [...prevState.list, prevState.inputValue],
            inputValue: ''
        }));
    }

    handleItemDelete(index) {
        this.setState((prevState) => {
            const list = [...prevState.list];
            list.splice(index, 1);
            return {list}
        });
    }
}

export default TodoList;

小组件:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class TodoItem extends Component {

    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    render() {
        const { content, test }  = this.props;
        // JSX -> createElemnt ->  虚拟DOM(JS 对象) -> 真实的DOM
        // return <div><span>item</span></div>
        return React.createElement('div', {}, React.createElement('span', {}, 'item'));
    }

    handleClick() {
        const { deleteItem, index } = this.props;
        deleteItem(index);
    }
}

TodoItem.propTypes = {
    test: PropTypes.string.isRequired,
    content: PropTypes.arrayOf(PropTypes.number, PropTypes.string),
    deleteItem: PropTypes.func,
    index: PropTypes.number
}

TodoItem.defaultProps = {
    test: 'hello world'
}

export default TodoItem;
  • Copyrights © 2019-2020 Rex