Each time working with in app we spend a lot of time to make , … Most actions in fact are CRUD for working with . redux react action types, action creators reducers redux store Let’s imagine that someone makes it for us… To make any react app we should create an empty project by using or configure with . create-react-app webpack babel _It’s a first part of tutorial where I’m going to show how to create react app from scratch._medium.com React app from scratch Usually I use webpack for to make a custom configuration. But this time I’ll use create-react-app. If you don’t have it (I hope you installed and on your PC) you can run next command: own projects node.js npm npm i -g create-react-app It will install the package as global so you can run it anywhere. Let’s run create-react-app to create a new directory for our project and create react app: create-react-app react-redux-example Small notice… For working with any node.js project you need to check . For example, you can find or commands. And to run it you can make command or short way (for predefined commands) / . package.json scripts section start test npm run start/ npm run test npm start npm test Another way is using . As it’s part of Facebook react ecosystem don’t forget to install it ( ). With yarn you can run the same commands: / . yarn npm i -g yarn yarn start yarn test And again, we are too lazy so we can just install another package — : ntl npm i -g ntl After that, you don’t need to research each package.json. Just run command in a directory of node.js project and you can see all commands. ntl Comeback to our app… We created a new react project. Let’s check it: cd react-redux-example To see all predefined commands run ntl: ntl We see start, build, test, eject commands: — starts our app, start — builds static files (js, css…) to deploy it on server, build — runs tests of our app, test — creates webpack config (after running eject command you’ll need to manage webpack by yourself). eject So now we can run our app. Run and then select command and press enter or make it manually by running ( ) command (but it’s not our way). ntl start npm start yarn start As we can see it works on port: 3000. If we open it in a browser ( ) we see our app: http://localhost:3000/ As we can see from page info to update our app we should change file. src/App.js Next, we should research our app structure and add redux. To see the tree structure of our app run next command (without node_modules): tree -I "node_modules" .├── README.md├── package.json├── public│ ├── favicon.ico│ ├── index.html│ └── manifest.json├── src│ ├── App.css│ ├── App.js│ ├── App.test.js│ ├── index.css│ ├── index.js│ ├── logo.svg│ └── registerServiceWorker.js└── yarn.lock So we are ready to create a form example. Our goals: create stateful component by extending React.Component see what is controlled components see what is state and how to manage it split our component: get stateless component and smart container see what is HOC and check other tools for working with state (recompose) So let’s create a new directory and create file with our form. src/form index.js mkdir src/formtouch src/form/index.js In real app, you will use and the best config is . With all scope of rules, you should split code into files. All JSX code you should keep in files. After looking into project structure you will know what each file does. eslint airbnb eslint config js/jsx *.jsx But using for our small lazy example we can make all code in files. create-react-app *.js Our simple form will be like this: React, { Component } 'react'; import from App Component {render() { (<form><h1>Our form example</h1><div><textarea /></div><div><input type="submit" value="Submit" /></div></form>);}} class extends return App; export default We need to update for adding our form: src/App.js React, { Component } 'react'; logo './logo.svg'; './App.css';** ** App Component {render() { (<div className="App"><header className="App-header"><img src={logo} className="App-logo" alt="logo" /><h1 className="App-title">Welcome to React</h1></header> </div>);}} import from import from import import Form from './form'; class extends return <Form /> App; export default And run command: start Here we just have a textarea input field and submit button. We can enter any text and press submit. But how can we get entered text? Now we have uncontrolled textarea component. To get entered text we can use but it’s not a react way. To work with react like a pro we need to use state. react ref links Let’s update our component and make it smart: React, { Component } 'react'; import from App Component {constructor(props) { (props); .state = {text: '',};} class extends super this onTextChange = (event) => { **this**.setState({ text: event.target.value }); }; render() { **return** ( <form> <h1>Our form example</h1> <div> <textarea onChange={**this**.onTextChange}> {**this**.state.text} </textarea> </div> <div> <input type="submit" value="Submit" /> </div> </form> ); } } App; export default Now we can get entered value but what about submit button? We should process entered value: React, { Component } 'react'; import from App Component {constructor(props) { (props); .state = {text: '',};} class extends super this onTextChange = (event) => { **this**.setState({ text: event.target.value }); }; onFormSubmit = (event) => { event.preventDefault(); alert(**this**.state.text); }; render() { **return** ( <form onSubmit={**this**.onFormSubmit}> <h1>Our form example</h1> <div> <textarea onChange={**this**.onTextChange}> {**this**.state.text} </textarea> </div> <div> <input type="submit" value="Submit" /> </div> </form> ); } } App; export default I added form submit handler. If we enter some test text and press submit we see an alert with the entered text: In real app, you can make ajax request instead of alert. So we see what is controlled and uncontrolled components — in our case it’s textarea. And we see what is smart component or container. In real production app if you want to be a pro you need to split logic into single responsibility components. In our case it’s splitting our big smart component into stateless component (or stupid component in some docs) and container. We get at least two files each with own single responsibility: stateless component will be just a view layer and container will be responsible for the state. Let’s create , and integrate it to our form: FormComponent FormContainer touch src/form/formComponenttouch src/form/formContainer And our code: FormComponent: React, { Component } 'react'; import from FormComponent Component {render() { (<form onSubmit={ .props.onFormSubmit}><h1>Our form example</h1><div><textarea onChange={ .props.onTextChange}>{ .props.text}</textarea></div><div><input type="submit" value="Submit" /></div></form>);}} class extends return this this this FormComponent; export default FormContainer: React, { Component } 'react'; import from FormContainer = FormComponent => { App Component {constructor(props) { (props); .state = {text: '',};} const return class extends super this onTextChange = (event) => { **this**.setState({ text: event.target.value }); }; onFormSubmit = (event) => { event.preventDefault(); alert(**this**.state.text); }; render() { **return** ( <FormComponent text={**this**.state.text} onTextChange={**this**.onTextChange} onFormSubmit={**this**.onFormSubmit} /> ); } } }; FormContainer; export default And our form: React, { Component } 'react'; FormContainer './formContainer'; FormComponent './formComponent'; import from import from import from Form = FormContainer(FormComponent); const App Component {render() { (<Form />);}} class extends return App; export default Here we see some interesting cases: we just split code and for stateless FormComponent we put state and handlers as properties. FormContainer does not render jsx code. It just puts state and handlers to FormComponent. FormContainer is not a react component. It’s high order component (HOC) — wrapper function. We put component as a parameter to function and it returns react component. HOC is an interesting pattern for react development. You can write your app in totally function way. Just imagine your react component can be just a JS function: props => jsx Don’t forget this arrow function. Let’s update our form component and make it functional: React 'react'; import from FormComponent = props => (<form onSubmit={props.onFormSubmit}><h1>Our form example</h1><div><textarea onChange={props.onTextChange}>{props.text}</textarea></div><div><input type="submit" value="Submit" /></div></form>); const FormComponent; export default Here we have a function. It gets props and returns JSX code. Less code, it’s more declarative. But what about our container? Should it be still a class? Working with redux it can be totally functional. Redux is a storage for global state. In some cases you will work with local state and you will create a classes. But speaking about declarative code don’t forget that we are too lazy for writing all code by ourselves. Our container is a HOC and there are a lot of production ready HOCs. The most interesting library for that is . You can find a lot of examples if you open . recompose documentation Next, I want to show how to make our container more functional. But first we should install it: npm i -S recompose or yarn add recompose After we can change our container. We will use withStateHandlers() { withStateHandlers } 'recompose'; import from FormContainer = withStateHandlers(({ text = '' }) => ({ text }),{onTextChange: () => event => ({text: event.target.value,}),onFormSubmit: ({ text }) => (event) => {event.preventDefault();alert(text);},},); const FormContainer; export default Again, less code, it’s more declarative. And in our case it’s functional. We even don’t need to import react because it’s just JS code. If we run our app we see the same results: So we just used ready recompose HOC for working with local state without making it manually. We finished our goals for this part: we saw controlled and uncontrolled components, stateless(functional) and smart (stateful) components — containers. We created own HOC and found a lot of ready HOCs created by other developers to make our development more faster and make our lazy life more easier :) Next step is adding redux… To add redux in our app as any other dependency we should first install it. In our case we need redux and to use it with react. react-redux yarn add redux react-redux And one thing — redux-logger: yarn add redux-logger It’s useful for debugging. Let’s create our store: touch src/store.js With next code: { createStore, applyMiddleware } 'redux'; logger 'redux-logger'; import from import from reducers './reducers'; import from store = createStore(reducers,applyMiddleware(logger)); const store; export default And reducers: touch src/reducers.js For now, it’s empty, but we will add reducer for our form component later: { combineReducers } 'redux'; import from combineReducers({}); export default Next step is creating provider for app — : src/index.js React 'react'; ReactDOM 'react-dom'; { Provider } 'react-redux'; './index.css'; App './App'; store './store'; registerServiceWorker './registerServiceWorker'; import from import from import from import import from import from import from ReactDOM.render( document.getElementById('root'));registerServiceWorker(); <Provider store={store}><App /></Provider>, It makes the store available to all container components in the application without passing it explicitly. You only need to use it once when you render the root component. And now we need to create , and . action types action creators, reducer But before we need to think about our actions: we need to change text submit our form. Action types: touch src/form/types.js With next code: FORM_TEXT = '@@form/TEXT'; FORM_SUBMIT = '@@form/SUBMIT'; export const export const In real production app you can create a lot of types/actions and each time you will have a naming problem. So if you don’t want to have a collision problems you need to add suffix to your types. I use @@moduleName/TYPE notation. In our case for form module I use , for example: or . @@form/TYPE @@form/TEXT @@form/SUBMIT Action creators: touch src/form/actions.js With code: { FORM_TEXT, FORM_SUBMIT } './types'; import from textAction = text => ({type: FORM_TEXT,text,}); export const submitAction = () => ({type: FORM_SUBMIT,}); export const And reducer: touch src/form/reducer.js With code: { FORM_TEXT } './types'; import from defaultState = {text: '',}; const (state = defaultState, action) => { (action.type) { FORM_TEXT: { ...state, ...action }; : state;}}; export default switch case return default return And don’t forget to add this reducer to global reducers (in next articles I’ll show how to use code splitting and reducer injecting). src/reducers.js: { combineReducers } 'redux'; import from form './form/reducer'; import from combineReducers({ form }); export default Next step is changing form container: { connect } 'react-redux'; { textAction, submitAction } './actions'; import from import from mapStateToProps = state => state.form; mapDispatchToProps = { textAction, submitAction }; const const connect(mapStateToProps, mapDispatchToProps); export default is a HOC, created to connect store to components. It gets parameters (mapStateToProps and mapDispatchToProps) and returns HOC. Connect is a selector, it filters data from the store. mapStateToProps creates dispatchers for actions. Using dispatchers you can change state. mapDispatchToProps A small changes of form component: React 'react'; import from FormComponent = props => (<form onSubmit={(event) => {event.preventDefault();props.submitAction();alert(props.text);}}><h1>Our form example</h1><div><textareaonChange={event => props.textAction(event.target.value)}value={props.text}/></div><div><input type="submit" value="Submit" /></div></form>); const FormComponent; export default Not so nice code as the previous example but here we have a global state and it’s still functional. So we are done. Let’s start app and see results: And submit: The same results. As you can see we didn’t make reducer for form submit action. Because form submitting usually finishes by sending ajax request or making other side effects. And it’s an interesting point ( , , , …) for another article. redux thunk redux-saga redux-promise redux-observable All console text we see thanks to . redux-logger Each time working with redux we need to make the same again and again: create , , , even . Imagine if someone makes it for us. action types action creators reducer container Try my small project: . redux-lazy Install it: yarn add redux-lazy Next create file: rl.js touch src/form/rl.js With next code: RL 'redux-lazy'; import from rl = RL('form');rl.addAction('text', { text: '' });rl.addAction('submit', {}); const new result = rl.flush(); const result; export default Now we can delete , , and . We have all this stuff from the box. types.js actions.js reducer.js form container Update src/index.js React 'react'; import from FormComponent './formComponent'; rl './rl'; import from import from Form = rl.Container(FormComponent); const App = () => <Form />; const App; export default Here we make functional component and we get Container from redux-lazy. src/reducers.js { combineReducers } 'redux'; import from rl './form/rl'; import from combineReducers({ [rl.nameSpace]: rl.reducer }); export default Here we get namespace and reducer from redux-lazy. And small updates in from component: React 'react'; import from FormComponent = props => (<form onSubmit={(event) => {event.preventDefault();props.submitAction();alert(props.text);}}><h1>Our form example</h1><div><textareaonChange={event => props.textAction( )}value={props.text}/></div><div><input type="submit" value="Submit" /></div></form>); const { text: event.target.value } FormComponent; export default And results: You can get a lot of stuff from redux-lazy: {nameSpace,types,actions,defaultState,reducer,mapStateToProps,mapDispatchToProps,Container,} = rl.flush(); const So just to repeat: Create redux-lazy object: const rl = new RL(‘form’); Add actions: rl.addAction(‘text’, { text: ‘’ }); the code. Flush That’s all. I think it’s useful for any (not only lazy) react/redux developer. To make possibility run it on your PC I created a . github repository To run it locally just make next steps: git clone cd react-redux-exampleyarnntl https://github.com/evheniy/react-redux-example.git _In this article I’m continue to discuss creating react redux app using redux-lazy._medium.com React — redux for lazy developers. Part 2 _It’s the last part of series about creating react redux app._hackernoon.com React — redux for lazy developers. Part 3 In this article we found how to easily create react app using , we saw what is / components, where we can store our state and how easy to work with react in a . More about this stuff you can read in my previous article: create-react-app stateless stateful functional way _As you may know working with react you can use functions or classes — work with stateless and stateful components. In…_blog.cloudboost.io React: functional way