Do you want to request a feature or report a bug? Bug.
What is the current behavior?

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem:
git clone https://github.com/English3000/Elixir.git
cd Elixir/functional_design/islands
git checkout refactor/bottom-up
cd apps/islands_interface/assets && npm i
cd ../../.. && mix phx.server
Go to
localhost:4000&& join a game
Islandw/ Hooks
- already tried w/o
useEffect
What is the expected behavior?
onBoard state hook updates value.
Logic works w/o hooks:

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
"^16.8.4"... then tried "^16.8.6"Function components capture values they rendered with.
So this behavior is expected.
Depending on what you want to do, there are a few workarounds 鈥斅燽ut usually there's also a way to structure your code in a clearer way.
https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
https://overreacted.io/how-are-function-components-different-from-classes/
I see.
_To summarize how to debug when defining a function within an SFC (stateless functional component) while using Hooks:_
state ~ useRef instead of useState when you want to set a value at a different stage in the lifecycle than constructor/1props w/ useEffect ~ if it remains stale, make sure you've added that specific stale prop to the dependencies arrayMy issues are now fixed! Thank you for the very helpful links!!
FYI: _Did you see my proposal for_ ReactDOM.hydrateElement/2?
Thanks for the posts, they were really enlightening!
I like the suggestion of using useReducer and pass the dispatch to a provider in order to use it in child components. I wonder if creating a custom hook that provides both state and actions, and pass them to the provider, would be a nice approach. Something like:
function useTodosReducer(reducer) {
const [data, dispatch] = useReducer(reducer)
function addTodo(text) {
dispatch({ type: 'add', text })
}
return {
data,
addTodo
}
}
function TodosApp() {
const store = useTodosReducer(todosReducer)
return (
<TodosDispatch.Provider value={store}>
<DeepTree todos={store.data} />
</TodosDispatch.Provider>
)
}
I'm gonna try it during the weekend.
I forgot to put here my findings on the useReducer hook.
After using hooks for a while now, I've found out that for the useReducer I'd prefer to create 2 contexts, one for the state and another one for the dispatch function.
const TodosState = createContext()
const TodosDispatch = createContext()
function TodosProvider({ children }) {
const [state, dispatch] = useReducer(todosReducer)
return (
<TodosState.Provider value={state}>
<TodosDispatch.Provider value={dispatch}>
{children}
</TodosDispatch.Provider>
</TodosState.Provider>
)
}
function useTodosState() {
return useContext(TodosState)
}
function useTodosDispatch() {
return useContext(TodosDispatch)
}
Having different contexts allows me to use the dispatch in components that doesn't need to re-render after the state changes.
I've also found pretty nice to implement the actions in the provider. So, instead of passing a dispatch to the context, I pass an actions API:
const TodosActions = createContext()
function TodosProvider({ children }) {
const [state, dispatch] = useReducer(todosReducer)
const actions = useMemo(() => {
function addTodo(text) {
dispatch({ type: 'add', text })
}
return { addTodo }
}, [dispatch])
return (
<TodosState.Provider value={state}>
<TodosActions.Provider value={actions}>
{children}
</TodosActions.Provider>
</TodosState.Provider>
)
}
function useTodosActions() {
return useContext(TodosActions)
}
Most helpful comment
Function components capture values they rendered with.
So this behavior is expected.
Depending on what you want to do, there are a few workarounds 鈥斅燽ut usually there's also a way to structure your code in a clearer way.
https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
https://overreacted.io/how-are-function-components-different-from-classes/