I'm trying to add simple React Context to my app. I create Context in "./components/DataProvider.js" that looks like this:
import React, { Component } from 'react'
const DataContext = React.createContext()
class DataProvider extends Component {
state = {
isAddButtonClicked: false
}
changeAddButtonState = () => {
if( this.state.isAddButtonClicked ) {
this.setState({
isAddButtonClicked: false
})
} else {
this.setState({
isAddButtonClicked: true
})
}
}
render() {
return(
<DataContext.Provider
value={{
isAddButtonClicked: this.state.isAddButtonClicked,
changeAddButtonState: () => {
if( this.state.isAddButtonClicked ) {
this.setState({
isAddButtonClicked: false
})
} else {
this.setState({
isAddButtonClicked: true
})
}
}
}}
>
{this.props.children}
</DataContext.Provider>
)
}
}
const DataConsumer = DataContext.Consumer
export default DataProvider
export { DataConsumer }
Which then I added to "./pages/_app.js"
import App, { Container } from 'next/app'
import DataProvider from '../components/DataProvider'
class MyApp extends App {
render () {
const { Component, pageProps } = this.props
return (
<Container>
<DataProvider>
<Component {...pageProps} />
</DataProvider>
</Container>
)
}
}
export default MyApp
And consume it in "./components/AddPostButton.js".
import React, {Component} from 'react'
import { DataConsumer } from './DataProvider'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
class AddPostButton extends Component {
render() {
return (
<div>
<DataConsumer>
{({ changeAddButtonState }) => (
<a onClick={changeAddButtonState}>
<FontAwesomeIcon icon={faPlus} color='#fff' />
</a>
)}
</DataConsumer>
</div>
)
}
}
export default AddPostButton
But I get this error "Cannot read property 'changeAddButtonState' of undefined". I'm using React 16.7 and NextJS 7.0.2. Don't know what is wrong.
The second question is should I use one Context for everything or just use them as Model in MVC pattern?
js. Starting from React v16. 3.0 , it is possible to use a new feature named context to pass data throughout the app.
To pass the state and functions via Context API, we need to wrap the entire app inside AppContext. Provider component where the AppContext is created by us in the previous step. In a Next. js app, we can see file _app.
React Context, introduced in React 16.3, is a way to share props globally across the React components tree. Some use cases could be managing and passing around user state or a selected theme with the whole of the app without having to manually pass props down to each button through the component tree.
Using the useState Hook for state management in Next. js. One of the most common ways to manage state is with the useState Hook. We will build an application that lets you increase the score by clicking the button.
I fixed it by moving changeAddButtonState to Context Component state so my DataProvider.js now looks like this
import React, { Component } from 'react'
const DataContext = React.createContext()
class DataProvider extends Component {
state = {
isAddButtonClicked: false,
changeAddButtonState: () => {
if (this.state.isAddButtonClicked) {
this.setState({
isAddButtonClicked: false
})
} else {
this.setState({
isAddButtonClicked: true
})
}
}
}
render() {
return(
<DataContext.Provider
value={this.state}
>
{this.props.children}
</DataContext.Provider>
)
}
}
const DataConsumer = DataContext.Consumer
export default DataProvider
export { DataConsumer }
And then in AddButton component I changed code to look like this
import React, {Component} from 'react'
import { DataConsumer } from './DataProvider'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
class AddPostButton extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<DataConsumer>
{(context) => (
<a onClick={context.changeAddButtonState}>
<FontAwesomeIcon icon={faPlus} color='#fff' />
</a>
)}
</DataConsumer>
</div>
)
}
}
export default AddPostButton
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With