React.js中的上下文API
React上下文api在版本16.3或最新版本中可以安全地用于生产中。添加上下文api的原因是,如果有一系列子组件,则避免传递prop。
在不使用上下文api的情况下,我们必须将道具传递给所有中间组件。另一种替代解决方案是使用第三方库(例如Redux)来维护中央存储。
了解道具传递问题
App.js→书籍道具→BookList.js→再次将书籍作为道具→Book.js
随着子组件数量的增加,传递道具的链条继续进行。
使用上下文api,React提供了一种提供方使用者方法来解决此问题。
Creating the context: BaseContext.js import React from 'react'; //这与Redux的createStore方法相同 const BaseContext = React.createContext(); export default BaseContext;
创建提供者
import BaseContext from './BaseContext';
class BookProvider extends Component {
state = {
books: {
book1: { name: 'React', price: 500 },
book2: { name: 'Angular', price: 450 }
}
};
render() {
return (
<BaseContext.Provider
value={{
books: this.state.books,
incrementPrice: selectedID => {
const books = Object.assign({}, this.state.books);
books[selectedID].price =books[selectedID].price + 1;
this.setState({
books
});
},
decrementPrice: selectedID => {
const books = Object.assign({}, this.state.books);
books[selectedID].price =books[selectedID].price - 1;
this.setState({
books
});
}
}}
>
{this.props.children}
</BaseContext.Provider>
);
}
}App.js
class App extends Component {
render() {
return (
<BookProvider>
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to my book store</h1>
</header>
<ProductBookList />
</div>
</BookProvider>
);
}
}在子组件中,我们可以使用使用者-
const Books = () => (
<BaseContext.Consumer>
{context => (
<Fragment>
<h4>Books:</h4>
{Object.keys(context.books).map(bookID => (
<Car
key={bookID}
name={context.books[bookID].name}
price={context.books[bookID].price}
incrementPrice={() =>context.incrementPrice(bookID)}
decrementPrice={() =>context.decrementPrice(bookID)}
/>
))}
</Fragment>
)}
</BaseContext.Consumer>
);通过使用contextapi,我们可以避免在React子组件中钻取道具。