After that, populate package.json and pages/index.tsx:
package.json
{"name":"test-app","scripts":{"dev":"next"}}
pages/index.tsx
exportdefault ()=><p>Hello World</p>;
And then, run the commands below:
# install dependencies$ npm install--save next react react-dom
$ npm install--save-dev typescript @types/node @types/react @types/react-dom
# run as development mode$ npm run dev
That's it!
Go to http://localhost:3000 and you'll see the Hello World!
Step 2: Build Redux TODO App (suddenly, I see)
I don't explain Redux architecture! lol
Just feel it, separation of the state and the view.
Define Features (ActionTypes and Actions)
Define the id of the action type in the constants/actionTypes.ts:
In the reducers/todo.ts, we define the initial state and how to handle it:
import{TODO_ONCHANGE,TODO_ADD,TODO_DELETE,}from'../constants/actionTypes';exportconstinitialState={// this is a TODO item which has one "value" propertyitem:{value:'',},// this is a list of the TODO itemsdata:[],};exportdefault (state=initialState,action)=>{// receive the type and item, which is defined in the `actions/index.ts`const{type,item,}=action;switch (type){caseTODO_ONCHANGE:{// BE CAREFUL!!!// DON'T USE THE REFERENCE LIKE THIS://// state.item = item;// return state; // this `state` is "previous" state!//// Please create a new instance because that is a "next" state//returnObject.assign({},state,{item,});}caseTODO_ADD:{// if the `item.value` is empty, return the "previous" state (skip)if (item.value===''){returnstate;}returnObject.assign({},state,{// clear the `item.value`item:{value:'',},// create a new array instance and push the itemdata:[...(state.data),item,],});}caseTODO_DELETE:{// don't use `state.data` directlyconst{data,...restState}=state;// `[...data]` means a new instance of the `data` array// and filter them and remove the target TODO itemconstupdated=[...data].filter(_item=>_item.value!==item.value);returnObject.assign({},restState,{data:updated,});}// do nothingdefault:{returnstate;}}};
And next, define reducers/index.ts which combines all reducers:
importReactfrom'react';import{compose}from'recompose';importTodofrom'./todo';constPage=(props)=>{// defined in the `containers/page.ts`, so the `props` is like this://// const {// item,// data,// onChangeTodo,// addTodo,// deleteTodo,// } = props;//return<Todo{...props}/>;};exportdefaultcompose()(Page);
import{NextPageContext,NextComponentType,}from'next';import{compose}from'recompose';import{connect}from'react-redux';importPagefrom'../containers/page';import{addTodo}from'../actions';import{Store}from'../store';interfaceIndexPageContextextendsNextPageContext{store:Store;}constIndexPage:NextComponentType<IndexPageContext>=compose()(Page);IndexPage.getInitialProps=({store,req})=>{constisServer:boolean=!!req;// we can add any custom data hereconst{todo}=store.getState();store.dispatch(addTodo(Object.assign(todo.item,{value:'Hello World!',})));return{isServer,};}exportdefaultconnect()(IndexPage);