i am trying to change the state of bulma model using useSelector and useDispatch
like this
const isState = useSelector((state) => state.isActiveState)
Model.js is:
import React from 'react'
import "../CSS/Careers.css"
import { useSelector, useDispatch } from 'react-redux';
import { stateCheck } from '../Redux/ActiveState'
export default function Modal() {
const isState = useSelector((state) => state.isActiveState)
const dispatch = useDispatch()
return (
<div>
<div
style={{ padding: "0rem 0.5rem 0rem" }}
className={`modal ${isState}`} //this should change the state to 'is-active'
>
<div onClick={() => dispatch(stateCheck())} className="modal-background"></div>
<div style={{ borderRadius: "1.5rem" }} className="modal-card">
<header
style={{
borderBottom: "1px solid white",
backgroundColor: "#F2F5FF",
}}
className=""
>
<div style={{ padding: "17px 19px 20px" }} className="is-flex ">
<p
style={{ color: "#7209B7" }}
className="modal-card-title has-text-weight-semibold"
>
Apply For Job
</p>
<button
onClick={() => dispatch(stateCheck())}
className="delete"
aria-label="close"
></button>
</div>
</header>
<section
style={{ backgroundColor: "#F2F5FF" }}
className="modal-card-body"
>
<div style={{ padding: "0rem 3rem 0rem" }} className="field">
<div className="control has-icons-left ">
<input
className="input "
// style={{ width: "100%" }}
type="text"
placeholder="Name"
/>
<span className="icon is-small is-left">
<i className="fas fa-user"></i>
</span>
</div>
</div>
<div style={{ padding: "0rem 3rem 0rem" }} className="field">
<div className="control has-icons-left ">
<input className="input " type="email" placeholder="Email" />
<span className="icon is-small is-left">
<i className="fas fa-envelope"></i>
</span>
</div>
</div>
<div
style={{ padding: "0rem 3rem 0rem" }}
className="file is-medium"
>
<label style={{ border: "3px sold #7209B7" }} className="">
<input className="file-input" type="file" name="resume" />
<span
style={{ backgroundColor: "#F2F5FF" }}
className="file-cta"
>
<span className="file-icon">
<i
style={{ color: "#7209B7" }}
className="fas fa-upload"
></i>
</span>
<span style={{ color: "#7209B7" }} className="file-label">
Choose a file…
</span>
</span>
</label>
</div>
<p
style={{
padding: "0rem 3rem 0rem",
fontSize: "15px",
color: "#fcb01a",
}}
>
Select CV or Resume
</p>
</section>
<footer
style={{
borderTop: "1px solid white",
textAlign: "center",
height: "20%",
backgroundColor: "#F2F5FF",
}}
className=" has-text-centered"
>
<div
style={{ paddingTop: "9px", textAlign: "center" }}
className=""
>
<button style={{ backgroundColor: "#fcb01a" }} className="button">
Submit
</button>
</div>
</footer>
</div>
</div>
</div>
)
}
my redux file ActiveState.js is:
import { createSlice } from '@reduxjs/toolkit'
export const ActiveState = createSlice({
name: 'isActiveState',
initialState: {
value: 0,
},
reducers: {
stateCheck: (state) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
if (state.value == 0){
state.value = 'is-active';
// console.log(state.value)
}
else{
state.value = 0;
// console.log(state.value)
}
}
},
})
export const { stateCheck } = ActiveState.actions;
export default ActiveState.reducer;
and store.js is:
import { configureStore } from '@reduxjs/toolkit'
import ActiveState from './components/Redux/ActiveState'
export default configureStore({
reducer: {
stateChecker : ActiveState,
},
})
index.js is:
import React from 'react';
import ReactDOM from 'react-dom';
import './components/CSS/index.css';
import App from './App';
import store from './store'
import { Provider } from 'react-redux'
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
I have added model to the component where i want to use it and to trigger the model i have used:
onClick={() => dispatch(stateCheck())}
dispatch is working fine i have checked with console.log
the problem is when i try to get redux state with:
const isState = useSelector((state) => state.isActiveState)
i get the following error in console:
Uncaught TypeError: dispatcher.useSyncExternalStore is not a function
i am following redux official documentation:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import store from './store/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Modal.js
// import '../CSS/Careers.css';
import React from 'react';
import { Button } from 'antd';
import { useSelector, useDispatch } from 'react-redux';
import { stateCheck } from './store/slice';
export default function Modal() {
const isState = useSelector((state) => state.stateChecker);
const dispatch = useDispatch();
console.log(isState);
return (
<div>
<Button onClick={() => dispatch(stateCheck(true))}>Open</Button>
<div
style={{
padding: '0rem 0.5rem 0rem',
// display: isState.value ? 'block' : 'none'
}}
className={`modal ${isState.value ? 'is-active' : ''}`} //this should change the state to 'is-active'
>
<div onClick={() => dispatch(stateCheck(false))} className='modal-background'></div>
<div style={{ borderRadius: '1.5rem' }} className='modal-card'>
<header
style={{
borderBottom: '1px solid white',
backgroundColor: '#F2F5FF'
}}
className=''
>
<div style={{ padding: '17px 19px 20px' }} className='is-flex '>
<p style={{ color: '#7209B7' }} className='modal-card-title has-text-weight-semibold'>
Apply For Job
</p>
<button onClick={() => dispatch(stateCheck(false))} className='delete' aria-label='close'></button>
</div>
</header>
<section style={{ backgroundColor: '#F2F5FF' }} className='modal-card-body'>
<div style={{ padding: '0rem 3rem 0rem' }} className='field'>
<div className='control has-icons-left '>
<input
className='input '
// style={{ width: "100%" }}
type='text'
placeholder='Name'
/>
<span className='icon is-small is-left'>
<i className='fas fa-user'></i>
</span>
</div>
</div>
<div style={{ padding: '0rem 3rem 0rem' }} className='field'>
<div className='control has-icons-left '>
<input className='input ' type='email' placeholder='Email' />
<span className='icon is-small is-left'>
<i className='fas fa-envelope'></i>
</span>
</div>
</div>
<div style={{ padding: '0rem 3rem 0rem' }} className='file is-medium'>
<label style={{ border: '3px sold #7209B7' }} className=''>
<input className='file-input' type='file' name='resume' />
<span style={{ backgroundColor: '#F2F5FF' }} className='file-cta'>
<span className='file-icon'>
<i style={{ color: '#7209B7' }} className='fas fa-upload'></i>
</span>
<span style={{ color: '#7209B7' }} className='file-label'>
Choose a file…
</span>
</span>
</label>
</div>
<p
style={{
padding: '0rem 3rem 0rem',
fontSize: '15px',
color: '#fcb01a'
}}
>
Select CV or Resume
</p>
</section>
<footer
style={{
borderTop: '1px solid white',
textAlign: 'center',
height: '20%',
backgroundColor: '#F2F5FF'
}}
className=' has-text-centered'
>
<div style={{ paddingTop: '9px', textAlign: 'center' }} className=''>
<button style={{ backgroundColor: '#fcb01a' }} className='button'>
Submit
</button>
</div>
</footer>
</div>
</div>
</div>
);
}
slice.js
import { createSlice } from '@reduxjs/toolkit';
export const ActiveState = createSlice({
name: 'isActiveState',
initialState: {
value: false
},
reducers: {
stateCheck: (state, action) => {
state.value = action.payload;
}
}
});
export const { stateCheck } = ActiveState.actions;
export default ActiveState.reducer;
store.js
import { configureStore } from '@reduxjs/toolkit';
import ActiveState from './slice';
export default configureStore({
reducer: {
stateChecker: ActiveState
}
});
It's not isActiveState. You should use the name of the reducer you specify in configureStore. stateChecker
const isState = useSelector((state) => state.stateChecker)
Now isState will have the value
.
CodePudding user response:
why do you use "ReactDOM.render" ? you use a technology called useSyncExternalStore which comes with React18. Dont you need use ReactDOM.createRoot(element,options).render(component) ?