Open vfonic opened 5 years ago
There is not currently a way to do this similar to how this is unable to track local state in class based components. I would be more then happy to extend reactotron to be able to work better with hooks but I haven't spent any time looking into how that might work. If there are ideas I am all ears
I thought I'd spend an hour looking at this just to get back involved in the project. I couldn't come up with a solution straight away, but I did record a video of the session if you're interested (Though I've only just noticed the quality / size of text is terrible! lesson learned) - its at https://www.youtube.com/watch?v=ycOyEWZfkKA
The best I could come up with as a solution is to leverage a function currying based approach. Its not great, but it achieves what you're after.
I've created a sample project to demonstrate at https://github.com/ianoshorty/reactotron-hooks-example/ - see for example usage https://github.com/ianoshorty/reactotron-hooks-example/blob/master/src/App.js to
Hey @ianoshorty! I am taking a look at the code but it looks like the video is blocked here in the states. I am assuming maybe due to some music?
Same here. I assumed it's because I'm in Thailand and didn't have VPN available at the time to switch to US.
Hey both - indeed it appears its been taken down due to the music coming out my alexa in the background! Oh well! Sorry about that. Hopefully you can still see the sample code though?
@ianoshorty youtube 🤦♂️
I can do this one! I have a similar logger that uses redux-logger with useReducer https://www.npmjs.com/package/useloggedreducer
I think this would be similar, but just use Reactotron.log
Any thoughts on what the API would look like? Would a developer just import this wrapper functions from Reactotron?
Hey @brooksbecton!
I think it will be a little bit more in depth than just Reactotron.log because that will just put the information on the timeline. I would suspect we would want to wire it up closer to how Redux and MST work which allows you to view the state in the state tab as it changes. The API for such a thing would require sending a few different events throughout time:
state.action.complete
- When an "Action" occurs.
state.backup.response
- When a backup is requested. This sends the current state. This one might be hard to handle in hooks I suspect.
reactotron.stateValuesResponse
- When state values are requested you have to respond with the values
reactotron.stateValuesChange
- When state values change you can push them up to reactotron with this.
I believe there would be a few more. One thing we could do is start out simple - get the ability to see hook values in the state tab then expand from there. As far as how the API to hook it up would look I think we have two real options:
For examples of what I would hope something like this would be capable of you can see https://github.com/infinitered/reactotron-mst/blob/master/src/reactotron-mst.ts
I have a few things going here: https://github.com/brooksbecton/reactotron-react-hooks
I am using the useEffect to track state
useEffect(() => {
Reactotron.trackState({ count, name });
}, [count, name]);
I able to see these values in Reactotron, but it doesn't currently respect any subscriptions.
What do you think about this approach?
Interesting approach but the more I think about it the more I am thinking it might make sense to monkey patch useReducer
or find how we can reach into the internals of React to hook into them because my concern with having to go out of your way to call trackState
is people just won't do it. One of the beautiful things about the Redux and MST implementation is they are largely "set it and forget it"... until you want to look at state. If we are going to require the user to setup each and every state call then that might defeat the purpose.
Yeah I think monkey patching is the only way you'll grab everything. I personally don't use the useReducer a whole lot, so I guess you would path useState too? That's the main reason I did the useEffect was so you could dump a lot of state in there to track it.
React state management hooks seem to be more single purpose than bigger state trees like Redux. I'm not familiar with MobX at all so can't speak to that.
useState
uses useReducer
under the hood in react-dom. I suspect react-native is the same. Technically hooks can actually be a larger state tree like Redux/MobX with the use of useReducer
. An idea someone threw out to me last week was if we can detect the component/function and then represent the different bits of the state in reactotron as just an array of values in the same order that they were registered. I would need to think through how to display that right but what if we tried to just track the component that is using the hook and monkey patching useReducer
I think that would be a great start.
Any advice on monkey patching or do you have any spots in the code that already do this?
You should be able to just import it and set the import to a new function. I suspect that should do the trick. If it doesn't we will have to rethink it probably. If it doesn't work maybe we just export our own useState
and useReducer
that stubs out when Reactotron is not available.
@brooksbecton this hook has been super helpful, thank you for posting it!
I've managed to successfully track my App's state using Reactron thanks to it. I'm not using typescript, so I refactored your hook ever-so-slightlty ( https://gist.github.com/Craigson/b6f6692153639bb187d52c7f43f518b7 ). I'm managing my state using a global context, wrapping each component in a Consumer and sit within the global context Provider. To track state, I'm simply doing so in my global reducer.
A very simplified example:
import Reactotron from "reactotron-react-native";
import actions from "./actions";
import { AsyncStorage } from "react-native";
import { UserModel } from "../models";
const initialState = {
user: UserModel,
...
};
function reducer(state, { type, props, asyncAction }) {
// shallow copy old state
let newState = { ...state };
// handle actions
switch (type) {
case actions.SET_USER:
newState.user = {
...newState.user,
...props.user
};
break;
}
Reactotron.trackState({ state: newState });
return newState;
}
export default reducer;
export { initialState };
Thanks again, super helpful!
ERROR TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[4], "./app/store/store").store')
Reactotron.trackState(rootReducer); Does not work
I just discovered this project. Great job! This looks super useful!
I'm trying to figure out if there's a way to track the "state"(s) of various React Hooks I'm using in my app?
I searched, but couldn't find any plugins.
Thanks!