第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>)
}