react基础.md

  1. 插值表达式 {}

  2. 在插值表达式中,可以使用js与jsx语法混用.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // write your code here
    const JSX = <div>
    <h1>{'h1'}</h1>
    <p>{'p'}</p>
    <ul>{ [1, 2, 3].map(item => {
    return <li>{item}</li>
    })}
    </ul>
    </div>;
  3. jsx注释 {/* */}

  4. 渲染 HTML 元素为 DOM 树
    使用reactRender(jsx组件, dom节点)

1
ReactDOM.render(JSX, document.getElementById('challenge-node'))
  1. react定义Html中的class属性, 不可以使用class, 只能使用className(class在js中为关键字)

  2. jsx中, 都存在自闭合标签, 就是不需要关闭标签 类似

    1
    <br />
  3. 好了, 在jsx语法中,也只能有一个父级标签

  4. 无状态组件

    1
    2
    3
    4
    5
    const mycomponent = () => {
    return (
    <div>some</div>
    )
    }
  5. 基于class语法创建一个 React 组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <h1>Hi</h1>
    );
    // change code above this line
    }
    };
  6. 用组合的方式创建一个 React 组件: z(x) = f(g(x))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    const child = () => {
    return (
    <div>
    { 'Hello child.' }
    </div>
    )
    }

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <div>
    <child></child>
    </div>
    );
    // change code above this line
    }
    };
  7. React 渲染嵌套组件
    没啥,也就组件嵌套组件.

  8. 渲染 class 组件为 Dom 树

1
ReactDOM.render(<componentName>, document.getElementById('challenge-node'))
  1. props传递

    1
    2
    3
    <App>
    <Welcome user={如果是变量的化} />
    </App>
  2. 默认的props-defaultProps

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const ShoppingCart = (props) => {
    return (
    <div>
    <h1>Shopping Cart Component{props.items}</h1>
    </div>
    )
    };
    // change code below this line
    ShoppingCart.defaultProps = {
    items: 0
    }
  3. React:使用 PropTypes 来定义你期望的 Props // 限制props的类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 使用 PropTypes
    const Items = (props) => {
    return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
    };

    // change code below this line
    Items.propTypes = {
    quantity: PropTypes.number.isRequired
    }
    // change code above this line

    Items.defaultProps = {
    quantity: 0
    };
  4. 访问props
    状态组件使用this关键字: this.props
    无状态组件使用入参props

  5. 创建带自身状态的组件: state

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
// initialize state here
this.state = {
// describe your state here
name: 'fuck'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
</div>
);
}
};
  1. 在render函数的return语句前可以放任意的js, 那么意味着我们可以在渲染之前, 对state进行处理.

  2. 原则: 改变组件状态必须要使用 this.setState

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'Initial State'
    };
    this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
    // change code below this line
    this.setState({
    name: 'React Rocks!'
    });
    // change code above this line
    }
    render() {
    return (
    <div>
    <button onClick={this.handleClick}>Click Me</button>
    <h1>{this.state.name}</h1>
    </div>
    );
    }
    };
  3. 在react组件里, 组件里的方法是访问不到组件的this的, 这个时候就要我们手动去修复这个问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    itemCount: 0
    };
    // change code below this line
    this.addItem = this.addItem.bind(this)
    // change code above this line
    }
    addItem() {
    this.setState({
    itemCount: this.state.itemCount + 1
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    <button onClick={this.addItem}>Click Me</button>
    { /* change code above this line */ }
    <h1>Current Item Count: {this.state.itemCount}</h1>
    </div>
    );
    }
    };
  4. input框数据双向绑定(万年问题)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class ControlledInput extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    input: 'xxx'
    };
    // change code below this line
    this.assignText = this.assignText.bind(this)
    // change code above this line
    }
    // change code below this line
    assignText(e) {
    this.setState({
    input: e.target.value
    })
    }
    // change code above this line
    render() {
    return (
    <div>
    { /* change code below this line */}
    <input type='text' value={this.state.input} onChange={this.assignText}/>
    { /* change code above this line */}
    <h4>Controlled Input:</h4>
    <p>{this.state.input}</p>
    </div>
    );
    }
    };
  5. 将 State 作为 Props 传递给子组件—-父子数据传递
    遵循两个原则:

  • 单向数据流
  • 最小状态组件原则
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 父子数据传递
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'CamperBot'
    }
    }
    render() {
    return (
    <div>
    <Navbar name={this.state.name} />
    </div>
    );
    }
    };

    class Navbar extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h1>Hello, my name is: {this.props.name} </h1>
    </div>
    );
    }
    };
  1. 父级向子集传递的不只是state, 也可以是function
    传递function的原因是, 给子组件一个修改state的机会.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    inputValue: ''
    }
    this.handleChange = this.handleChange.bind(this);
    }
    handleChange(event) {
    this.setState({
    inputValue: event.target.value
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    {this.state.inputValue}
    <GetInput input={this.state.inputValue} handleChange={this.handleChange}/>

    <RenderInput input={this.state.inputValue} />

    { /* change code above this line */ }
    </div>
    );
    }
    };

    class GetInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Get Input:</h3>
    <input
    value={this.props.input}
    onChange={this.props.handleChange}/>
    </div>
    );
    }
    };

    class RenderInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Input Render:</h3>
    <p>{this.props.input}</p>
    </div>
    );
    }
    };
  2. 使用生命周期方法Overview

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    componentWillMount()
    // 即将挂载
    componentDidMount()
    // 挂载后
    componentWillReceiveProps()
    // 将要接收props
    shouldComponentUpdate()
    // 组件更新
    componentWillUpdate()
    // 组件即将更新
    componentDidUpdate()
    // 组件更新后
    componentWillUnmount()
    // 组件卸载
  3. componentDidMount — 组件装载到 DOM 后会调用
    这个生命周期:

  • 一般是放数据请求.请求后把数据放入模板, 再进行渲染.类似我们vue会把请求初始化放到created()
  • 挂载浏览器事件(特指全局的哦, 比如按回车然后, 执行某些搜索, 我们在componentDidMount周期里挂载, 在componentWillUnmount里卸载这个事件)
  1. componentWillReceiveProps — 组件接收到props或者props更新就会触发: 入参默认为该次传入的props

  2. componentDidUpdate — 组件再次重新渲染会触发: 入参默认为该次传入的props

  3. componentWillMount/componentDidMount — 首次渲染, 首次卸载会触发

  4. shouldComponentUpdate — 该生命周期控制组件是否需要更新, 入参默认为nextProps, nextState, 出参必须要一个boolean值, 告诉react是否需要更新该组件,因为, react的行为是, 如果传入了props那么无论怎样都会去更新组件, 触发渲染.(这个生命周期是作为一个优化提出的)

  5. react中的内联样式
    在react使用样式的方式有两种

  • 正常导入
  • 使用内联样式
    1
    <div style={{color: "yellow", fontSize: 16}}>Mellow Yellow</div>
    要点: 1. style中只接受对象 2. 不识别连字符, 要使用驼峰命名
  1. React:在 React Render 方法中使用 JavaScript
    在render函数的return语句之前,我们可以使用任意的js
  1. 使用 If/Else 条件进行渲染
    记住, 这种判断一般都抽离出来成为一个逻辑,不要再jsx中写入太多逻辑.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    let content
    if(this.state.toggleDisplay) {
    content = <h1>Hello</h1>
    } else {
    content = ''
    }
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {content}
    </div>
    );
    }
    };
  2. 使用 && 获得更简洁的条件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {this.state.display && <h1>markup</h1>}
    </div>
    );
    }
    };
  3. 使用三元表达式进行条件渲染

    1
    2
    3
    4
    5
    const buttonOne = <button onClick={this.submit}>Submit</button>;
    const buttonTwo = <button>You May Enter</button>;
    const buttonThree = <button>You Shall Not Pass</button>;

    this.state.input === '' ? buttonOne : (this.state.userAge >= 18 ? buttonTwo : buttonThree)
  4. 服务端渲染(待续)

完结撒花