React曾经忽略的知识点(下)

1.JSX渲染

想让类似 falsetruenull 或 undefined 出现在输出中,你必须先把它转换成字符串 :

<div>
  My JavaScript variable is {String(myVariable)}.
</div>

 

2.获取上传文件的信息

 

class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.files[0].name}`
    );
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input
            type="file"
            ref={input => {
              this.fileInput = input;
            }}

          />

        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

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

 

3.防止突变,添加数组的方法

  1.用concat重写成

handleClick() {
  this.setState(prevState => ({
    words: prevState.words.concat(['marklar'])
  }));
}

  2.用ES6支持数组的spread语法

handleClick() {
  this.setState(prevState => ({
    words: [...prevState.words, 'marklar'],
  }));
};

  

function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}

 

  3.不污染原始对象,使用Object.assign方法

function updateColorMap(colormap) {
  return Object.assign({}, colormap, {right: 'blue'});
}

updateColorMap现在会返回一个新对象,而不会改变之前的旧对象。Object.assign在ES6中,需要polyfill支持。

如果使用Create React App,默认情况下 Object.assignspread对象都可以使用。

 4.Context

Context 设计目的是为共享那些被认为对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。

  1.React.createContext

const {Provider, Consumer} = React.createContext(defaultValue);

创建一对 { Provider, Consumer }。当 React 渲染 context 组件 Consumer 时,它将从组件树的上层中最接近的匹配的 Provider 读取当前的 context 值。

如果上层的组件树没有一个匹配的 Provider,而此时你需要渲染一个 Consumer 组件,那么你可以用到 defaultValue 。这有助于在不封装它们的情况下对组件进行测试。

  2.Provider

<Provider value={/* some value */}>

React 组件允许 Consumers 订阅 context 的改变。

接收一个 value 属性传递给 Provider 的后代 Consumers。一个 Provider 可以联系到多个 Consumers。Providers 可以被嵌套以覆盖组件树内更深层次的值。

  3.Consumer

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

一个可以订阅 context 变化的 React 组件。

接收一个 函数作为子节点. 函数接收当前 context 的值并返回一个 React 节点。传递给函数的 value 将等于组件树中上层 context 的最近的 Provider 的 value 属性。如果 context 没有 Provider ,那么 value 参数将等于被传递给 createContext() 的 defaultValue 。

  注意

每当Provider的值发送改变时, 作为Provider后代的所有Consumers都会重新渲染。 从Provider到其后代的Consumers传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新时,后代Consumer也会被更新。

  举个例子:

index.js

import React, { Component } from 'react';
import {ThemeContext,themes,UserContext} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button'

function Toolbar(props){
  return(
    <ThemeContext.Consumer>
      {({theme,toggleTheme})=>(
        <UserContext.Consumer>
          {user=>(
            <ThemeTogglerButton user={user} theme={theme} toggleTheme={toggleTheme}/>
          )}
        </UserContext.Consumer>
      )}
    </ThemeContext.Consumer>
  );
}

class LotsContext extends Component {
  constructor(props){
    super(props);

    this.toggleTheme = ()=>{
      this.setState(state=>({
        theme:
          state.theme === themes.purple
            ?themes.pink
            :themes.purple,
      }));
    };
    this.state={
        theme:themes.pink,
        toggleTheme:this.toggleTheme,
        user:'mosquito~'
    };
  }
  render() {
    const {user,theme,toggleTheme} = this.state;
    return (
        <ThemeContext.Provider value={{theme,toggleTheme}}>
          <UserContext.Provider value={user}>
            <Toolbar />
          </UserContext.Provider>
        </ThemeContext.Provider>

    );
  }
}


export default LotsContext;

theme-context.js

import React from 'react';
export const themes = {
    pink:{
        background:"pink",
    },
    purple:{
        background:"purple",  
    },
};

export const ThemeContext = React.createContext({
    theme:themes.pink,
    toggleTheme:()=>{},
});

export const UserContext = React.createContext({
    user:"mosquito~"
});

theme-toggler-button.js

import React from 'react';
import {ThemeContext} from './theme-context';

function ThemeTogglerButton(props){
    return(
        <ThemeContext.Consumer>
            {({theme,toggleTheme}) => (
                <div
                onClick={toggleTheme}
                style={{width:'100px',height:'100px',backgroundColor: theme.background}}
                >
                    {props.user}
                </div>

            )}
        </ThemeContext.Consumer>
    );
}

export default ThemeTogglerButton;

运行结果:

 

 

posted @ 2018-09-28 14:47  mosquito~  阅读(361)  评论(0编辑  收藏  举报