《React全家桶:前端开发与实例详解》读书笔记2

779 阅读2分钟

第4章 JSX和虚拟DOM

1、虚拟DOM

  • 虚拟DOM:表示实际DOM的JavaScript 对象树,一个由ReactElement组成的树。React会把它变成真正的DOM。

为什么不使用实际的DOM?跟踪DOM的状态以将其操作为需要的形式困难;修改DOM代码高,会导致性能下降。

  • ReactElement:虚拟DOM中DOM元素的表示,通过createElement()创建。
  • createElement():3个参数:DOM元素类型、元素的props、元素的子元素 子元素必须是ReactNode对象,可以是以下三种之一:ReactElement、ReactText(字符串或数字)、ReactNode数组
  • ReactDOM.render():渲染ReactElement的方法,3个参数:虚拟树的根节点、挂载位置的真实DOM、组件渲染/更新后的回调函数
var boldElement = React.ReactElement('b'null,'TEXT')
var mountElement = document.querySelector('#root')
ReactDOM.render(boldElement,mountElement)

2、JSX

替我们处理好创建ReactElement对象的工作;

JSX陷阱
  • class与className:class是JavaScript的标识符,因此在JSX中使用className来标识类;
  • for与htmlFor:for是JavaScript的标识符,因此在JSX中使用htmlFor传递属性;
  • data-:在HTML原生组件上想应用HTML没有涵盖的属性,必须在属性前面加上data-;而自定义组件可以应用任何属性。

第5章 具有props、state、children的高级组件配置

一、props

1、PropTypes

PropTypes:验证props传递的值的一种办法

class MapComponent extends React.Component {
    static propTypes = {// 通过设置静态类propTypes属性来定义propTypes
        zoom:PropTypes.number,
        plsce:PropTypes.object,
        markers:PropTypes.array
}
2、getDefaultProps()

getDefaultProps():获取默认props

class MapComponent extends React.Component {
    static getDefaultProps = {// 通过设置静态属性getDefaultProps
        zoom:1
}

二、上下文context

全局公开的属性,React负责将context变量通过组件树向下传递。通过React.createContext()定义Provider/Consumer组件上下文的context。

  • Provider:该组件专门用于传递上下文;
  • Consumer:该组件是Provider的子组件,从Provider组件访问该上下文;
export const ThemeContext = React.createContext(themes.dark);// React.createContext接收一个上下文提供的默认值

class App extends Component {
  state = {theme: themes.dark};
  changeTheme = evt => {// 修改全局变量
    this.setState(state => ({
      theme: state.theme === themes.dark ? themes.light : themes.dark
    }));
  };
  render() {// ThemeContext.Provider传递了value
    return (
      <div className="App">
        <ThemeContext.Provider value={this.state.theme}>
          <Header />
          <button onClick={this.changeTheme}>Change theme</button>
        </ThemeContext.Provider>
      </div>
    );
  }
}

export const Header = props => (// ThemeContext.Consumer的子项是一个方法,通过方法访问传递下来的属性
  <ThemeContext.Consumer>
    {theme => (
      <header
        className="App-header"
        style={{backgroundColor: theme.background}}
      ></header>
    )}
  </ThemeContext.Consumer>
);

多个上下文

export const Body = props => (
  <ThemeContext.Consumer>
    {theme => (
      <header
        className="App-header"
        style={{backgroundColor: theme.background}}
      >
        <UserContext.Consumer>
          <h1>{user => (user ? 'Welcome back' : 'Welcome')}</h1>
        </UserContext.Consumer>
      </header>
    )}
  </ThemeContext.Consumer>
);

三、无状态组件

由于有状态组件的可变性和复杂性,因此鼓励使用无状态组件。

无状态组件:通过props向下传递参数,只有render()方法的函数式组件,并不是一个类。使用无状态组件可以提高性能,因为组件的设置和拆卸少,无生命周期方法。

const Header = function(props) {
  return (<h1>{props.headerText}</h1>)
}