-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docs: Rewrite tutorial to show hooks as the primary API #1574
Comments
@markerikson is there any way I can help out with this? |
Sure! No one's volunteered to tackle it yet, so it's up for grabs if you'd like to work on it. For reference, here's the new "Redux Essentials" core docs tutorial where I covered use of the hooks as the default: https://redux.js.org/tutorials/essentials/part-1-overview-concepts I'd suggest looking through that and the React-Redux tutorial, coming up with a suggested plan / outline for a rework, and then post that here and we can discuss it. |
Okay, will jump on this and get back to you |
Related to this, we need more details on what https://www.reddit.com/r/reactjs/comments/cc9ehv/need_help_with_new_redux_hooks/etmedoh/ |
It occurs to me that a good approach here might just be to copy-paste/port the "UI and React" page from the "Redux Fundamentals" tutorial I wrote for the core docs: |
A couple people have indicated interest in doing this, but no one has actually done so yet. Still interested in having someone tackle this! |
I'm interested in doing that :) |
I'd be happy to work with you on that as well. I've worked through the essentials and fundamentals tutorials very recently so the conventions and style are still pretty fresh. |
@ligabloo , @wjohnso-insight : Cool :) Per my tweets and my comment above, I think that the best (and hopefully easiest) approach is to start by copying the content from that "Redux Fundamentals: UI and React" page. We'd need to make updates to the content to:
But I do think that reusing that page gives us 90% of the content we need without having to rewrite it from scratch. As much as I love the work that @wgao19 did on the existing One other issue: right now, the React-Redux docs have this annoying "versioned docs" setup, which makes working on docs content a lot more complicated. Per #1693 , I actually want to drop that versioning setup. I may try to tackle that myself tomorrow to help make it simpler to work on this. |
Sounds like a plan. I like the idea of reusing sections from the existing docs. @markerikson Would you recommend reading up on Docusarus versioning just to get a feel for the terrain and for some context or is that overkill? |
It's probably overkill for now. Really, there's a good chance that I may have it turned off completely by this time tomorrow :) The short version is that the Meanwhile, the "Current (7.2)" version is actually located under I'd say just create a new |
Gotcha! |
I'm really glad we're at this point! I think it's the right direction, especially since reactjs.org itself is undergoing the same transition to hooks-first docs. I've been using hooks and the react-redux hooks since they've come out and I have a few opinionated takes I wanted to share. If you agree with any of these, feel free to take inspiration in the docs (otherwise, feel free to ignore 😅) Click to reveal wall of textWhy hooks first?Hooks are the React team's solution to many problems in React. They represent the continued future of React and as stated before, they're also transitioning the current docs to be hooks-first. I think it's important to state why hooks should be the preferred option over
Easier to use with TypeScriptThis one is just easy to get out of the way. React hooks were built with static typing in mind. Properly adding types to a higher-order component is complex and confusing. Hooks return the values they inject inline, types intact. This holds true for react-redux. Easier to compose with other pieces of global stateReact hooks were built for composition. If you want to join two or more pieces of state, you can do so in the component inline now. import { useSelector } from 'react-redux';
import { useParams } from 'react-router';
function Component() {
// global state from react-router
const { id } = useParams();
// global state from redux combined with state from react-router
const item = useSelector(state => state.entities[id]);
// local state using the redux state as an initial value
const [active, setActive] = useState(item.active);
// ...
} And custom hooks can elevate these into reusable pieces: import { useSelector } from 'react-redux';
import { useParams } from 'react-router';
function useItem() {
const { id } = useParams();
const item = useSelector(state => state.entities[id]);
return item;
}
function Component() {
const item = useItem();
} This contrasts heavily with some previous best practices back in the day. For example, the purpose of the proejcts Easier to understand due to less indirection
If you want to grab a particular item from state, you can directly return it from import { selectItem } from '../actions';
function Component() {
const { id } = useParams();
const item = useSelector(state => state.items[id]);
if (!item) {
return <>Loading…</>;
}
return (
<>
<h1>{item.title}</h1>
<button
onClick={() => {
dispatch(selectItem(id));
}}
>select this item</button>
</>
);
} Compare this with the import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { selectItem } from '../actions';
const mapStateToProps = (state, ownProps) => {
const { location } = ownProps;
const { id } = location.match;
const item = state.items[id];
return { item }
};
// you could return dispatch directly however, that's not the meta for redux
// with useDispatch, you don't have a choice
const mapDispatchToProps = { selectItem };
class Component extends React.Component {
render() {
const { item, selectItem, location } = this.props;
const { id } = location.params;
if (!item) {
return <>Loading…</>;
}
return (
<>
<h1>{item.title}</h1>
<button
onClick={() => selectItem(id)}
>select this item</button>
</>
);
}
}
// it's very hard to add types to this
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(Component)); Works well with the default React hooksIn particular, I've found it useful to intentionally not calculate values in // note: this is an intentionally complex/contrived example
import { memo, useMemo } from 'react';
import { useSelector } from 'react-redux';
function Wrapper() {
const { id } = useParams();
const item = useSelector(state => state.items[id]);
const { sublist } = item;
const expensiveCalculation = useMemo(() => {
return sublist.reduce((acc, next) => { /* ... */ }, {});
}, [sublist]);
return <ExpensiveRenderingComponent expensiveCalculation={expensiveCalculation} />;
}
const ExpensiveRenderingComponent = memo(({ expensiveCalculation }) => {
// ...
}); And function Component() {
const dispatch = useDispatch();
const count = useSelector(state => state.screen.count);
const greaterThanFive = count > 5;
useEffect(() => {
if (greaterThanFive) {
dispatch(showMessage());
}
}, [greaterThanFive, dispatch]);
return // ...
} In general, I like to be as React idiomatic as possible and hooks-first is the way 😎 Anyway, that's all I got! |
@markerikson I also like the idea of reusing the existing redux fundamentals docs, will make it easier to get started for sure. @wjohnso-insight I appreciate it! How would we go about collaborating in this case? We checkout a new branch from master, push it and then work on it simultaneously? Also, how could we split the work? @ricokahler those seem like good points to me! |
@ligabloo Yeah, if you're going to collaborate on this, I'd suggest that one of you should create a fork of this repo, give the other person collaborator permissions on that fork, and both push changes to that branch as appropriate. Once you've got something ready, you can PR from that fork back over to here. I'm playing around with removing the versioning right now, so I think you can safely assume that the new file should live in |
@ligabloo Looking forward to working with you! If you want to make the fork and add me as a collaborator that works for me. Tomorrow I'll take a look at the old code base and the reference from the UI & React tuts and star putting some cards together and we can divvy up from there. Sound good? |
@wjohnso-insight sounds awesome! I'll also start tomorrow since it's already kinda late here 😅 I'm setting up the fork and adding you as a collaborator so we can be ready to go. |
Great, appreciate both of you jumping in on this! :) Please feel free to ping me over in the Reactiflux Discord |
aaaand done! just nuked the versioning setup, so you'll probably want to go ahead and do a fresh pull from |
@wjohnso-insight I copy-pasted the tutorial from redux essentials into I suppose we could start by nuking the "Introduction" and "Integrating Redux with a UI" sections and replace them with more specific introductory content about the tutorial and redux-react themselves, right? @markerikson about the existing links - do we want to keep them redirecting to redux official docs or do we want to replace them with something else? I see some of them link to other steps of the essentials tutorials, would linking directly to them be confusing out of the original context? |
Yeah, those are the sorts of "content edits" I'm describing. I'd like this to be a standalone document in the React-Redux repo, instead of blatantly being "the middle of another tutorial we ripped out and copied". However, it would be good to point to the core docs "Fundamentals" tutorial in a "Prerequisites" info box at the top of the page, similar to how the first pages of the "Fundamentals" and "Essentials" tutorials start by saying "you should know HTML, JS, and React": https://redux.js.org/tutorials/essentials/part-1-overview-concepts I can see arguments both ways on whether to keep the "Integrating Redux with a UI" section. On the one hand, it's not strictly necessary to read that to know how to use the hooks. On the other hand, seeing that example should make it more clear what the hooks are doing and how they work, conceptually. Eh... let's pull that section out of here for now to keep this focused on "how to use it". I've been meaning to add a "how it works" page to the React-Redux docs for years now :) we can drop that material in there. |
@ligabloo Have you made me a contributor to your fork yet? |
Yep - I sent you an invitation, did you get anything in your email / notifications? |
Ope! Got sent to spam. I'm in now. Also, are you on Discord? Hit me up. @chef_will |
@wjohnso-insight tried finding you there, but I think I need the four-digit tag as well 😛 |
My b! chef_will#5730 |
Just a quick update on behalf of @ligabloo and myself. Our refactor to Hooks first documentation is proceeding well. @ligabloo has re-written the todo list application using hooks and RTX, here . I drafted the outline for the new tutorial copy here and have started pushing commits to our fork based on this outline. I should have the first draft together in the next day or so. Once we have a working draft we will perform some quick-and-dirty QA testing by asking Reactiflux members to complete the tutorial and soliciting them for notes/comment. Once we have amended a final draft and incorporated user comment we will open a PR with our fork. |
Nice! My experience with CodeSandboxes for examples is that they work best when the code is actually in a Github repo, and the sandbox is pointed to a specific branch or tag. You can see that in the existing tutorials. My suggestion would be that we should create a |
@wjohnso-insight @ligabloo hey, wanted to follow up on this - are you still working on the tutorial migration? |
@markerikson hey, Mark! So, we've had a bit of a pause since last month - personally, I've been kind of busy with work and that messed up my schedules and such, but yeah, I still intend to continue working on this. This is the progress we've made so far: https://github.com/ligabloo/react-redux/blob/master/docs/tutorials/hooks.md I'd appreciate if you could give us feedback on what we've written (well, mostly @wjohnso-insight, I've helped with the code samples and some minor suggestions) so far and if it matches what you're expecting out of the tutorial 😃 |
@ligabloo gotcha, thanks for the update! Glancing at that page, I'd actually suggest cutting down on the amount of explanation of basic store setup. Ultimately the goal here is to teach setting up the React-Redux portion and using it, vs teaching Redux itself. I do note that we don't really have a good spot that explains "how to set up Perhaps we could add one other "Quick Start" tutorial to the Redux core docs. We've already got one in the RTK docs at https://redux-toolkit.js.org/tutorials/quick-start , and it would seem reasonable to put that in the Redux docs. So, I think my main suggestion here would be point to "Understanding of Redux core concepts" as a prerequisite, and focus this section more on the React-Redux APIs. |
Hello @markerikson, I've been thinking on this from time to time, and it seems like I can't never really find time to get back to it. 😞 I'm sorry for taking so long to tell, but I decided it would be best to do it know rather then hoarding this task even longer while some other person might be interested in going through with it. I'll try to talk with some of my work colleagues to see if anyone is interested in contributing (and able to do so). Still, I hope to be able to help with something else in the future, since Redux has been a fundamental tool that I've used daily for years. |
@ligabloo no worries, I appreciate the effort, and I totally understand being too busy! Could you do me a favor? Go ahead and open up a PR with whatever content you have so far, and create issues here in the repo matching what you were planning to do. That way someone else can pick up with the effort. |
We're now at a point where I'm comfortable teaching our hooks API first (which I'm also doing right now as I work on the new "Quick Start" Redux core tutorial page).
Given that, it would be nice to convert the React-Redux tutorial over. Would still be helpful to have the
connect
intro somehow as well, albeit secondary.The text was updated successfully, but these errors were encountered: