Trying to use Context.API to create a global state and pass it to multiple components. The state will store a few properties including a TwilioToken, device type and a name. I have a component SignupForm that renders a button. When the button is clicked, this triggers a function handleSubmit that takes a username and passes the username as an argument to another function setupTwilio. This function sends the username to an end point that interacts with Twilio Programmable Voice API, sending back a TwilioToken and device type. I then want to update my global state with the Twilio Token and device type and then redirect the user to another page /rooms
Problem is I don't seem to be updating my global state at all, when I console.log(state.TwilioToken) in the component rendered after handleSubmit I get null
Here is my context provider:
const initialState = {
nickname: '',
selectedRoom: null,
rooms: [],
createdRoomTopic: '',
twilioToken: '',
device: null
};
const RoomContext = createContext(null);
export const RoomContextProvider = ({ children }) => {
const[state, setState] = useState(initialState);
return (
<RoomContext.Provider value={[state, setState]}>{children}</RoomContext.Provider>
)
};
export const useGlobalState = () => {
const value = useContext(RoomContext)
if(value === undefined) throw new Error('Please add RoomContextProvider');
return value;
}
My signupform
import { useGlobalState } from '../../context/RoomContextProvider';
...
//without useState() I get the error Uncaught TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
const [state, setState] = useState(useGlobalState());
...
const handleSubmit = e => {
e.preventDefault();
const nickname = user.username;
setupTwilio(nickname);
history.push('/rooms');
}
const setupTwilio = (nickname) => {
console.log('inside setupTwilio function', nickname)
fetch(`http://127.0.0.1:8000/voice_chat/token/${nickname}`)
.then(response => response.json())
.then(data => {
const twilioToken = data.token;
const device = new Device(twilioToken);
device.updateOptions(twilioToken, {
codecPreferences: ['opus', 'pcmu'],
fakeLocalDTMF: true,
maxAverageBitrate: 16000
});
device.on('error', (device) => {
console.log("error: ", device)
});
setState((state) => {
return {...state, device, twilioToken}
});
})
...
};
return (
<button className="button button-primary button-wide-mobile button-sm"
onClick={handleSubmit}> Start Coding
</button>
);
When I console.log my state in the component rendered I get null
import { useGlobalState } from '../../context/RoomContextProvider';
...
const [state, setState] = useState(useGlobalState());
console.log('global state token is', state.twilioToken)