DEV Community

loading...

Creating a editable dynamic JSON table in React part 2

sajrashid
・3 min read

Part 2

This articles is part 2 of a series, part 1 is here

NB: We're using craco to help with our builds as we can use Tailwind to locally test our table

Clone this branch

git clone -b boilerplate https://github.com/sajrashid/React-Dynamic-Json-Table/tree/boilerplate

Install node modules
Yarn

Run the app using
Yarn start

You should see the homepage. Have a look around it's a modified boiler plate template built from create-react-app.

Folder structure has been setup, src/npm-component/react-dj-table is where the table will live, a Tests folder that replicates the same folder structure and some mock data.

A word about complex state

Managing state using the useState hook is fine for small components, for a component with complex state we need to utilise the useReducer hook.

Whenever state values change that depend on other states values, you're getting into the realms of managing complex state. For anyone that's tried reducers are a game changer.... redux anyone ?

ℹ️ info- Did you know, under the covers useState actually calls useReducer!

Setting up the reducer

in the src/npm-component/react-dj-table/reducers folder

create a tablereducer.js & actions.js file

add the following code to actions.js

export const ACTIONS={

    TESTSTATE:'teststate'
}
Enter fullscreen mode Exit fullscreen mode

and to tablereducer.js

import { ACTIONS } from './actions'

export const TableReducer = (state, action) => {

    switch (action.type) {
        case ACTIONS.TESTSTATE:
            state.testValue ++
            return { ...state }
        default:
            return state

    }
}
Enter fullscreen mode Exit fullscreen mode

So far we have set-up the reducer, with a single ACTION, that increments a value and save that value to state, pretty straight-forward.

in the react-dj-table folder create a file called table.js

Here we need to set-up initial state and the reducers dispatch function.

add the following code to table.js

import React, { useReducer } from 'react'

import { TableReducer } from '../react-dj-table/reducers/tablereducer'

const Table = (props) => {

    const initialState = {
        testValue: 5 
    }

    const [state, dispatch] = useReducer(TableReducer, initialState)

}

export default Table

Enter fullscreen mode Exit fullscreen mode

take a moment to digest the above code, self explanatory so far hopefully.

..... ready ? , it's time to call the reducer via dispatch

dispatch({ type: ACTIONS.TESTSTATE })
Enter fullscreen mode Exit fullscreen mode

We need to call the reducer and supply the Action name from the actions file, we don't need to use defined actions & they don't need to be called action either. It's just a conventions & preferences thing.

ℹ️ Tip - It does help while learning as you'll get less typo's.

Update our table.js file

import React, { useReducer } from 'react'

import { ACTIONS } from '../react-dj-table/reducers/actions'
import { TableReducer } from '../react-dj-table/reducers/tablereducer'

const Table = (props) => {

    const initialState = {
        testValue: 5
    }

    const [state, dispatch] = useReducer(TableReducer, initialState)

    const buttonClick = () => {
        dispatch({ type: ACTIONS.TESTSTATE })
    }

    return (
        <div>
            <button onClick={buttonClick}>Increment</button>
            {state.testValue}
        </div>
    )

}
export default Table
Enter fullscreen mode Exit fullscreen mode

We have a added a button with a click funtion that calls the reducers dispatch functions passing in an action.

Add the table (ok, it's not really a table but we can pretend for testing purposes) to the src/pages/home.js page

import React from "react";
import Table from '../npm-component/react-dj-table/table'

const Home = props => {
  return (
    <div className="flex justify-center w-full h-full mt-4">
     <Table />
    </div>
  )
}

export default Home;

Enter fullscreen mode Exit fullscreen mode

Go to your page click the increment button.

Awesome we have a working reducer!!!

🤓🤓🤓

In the next part we're going to add some data, build our rows, cells and perhaps add a sort. Then maybe accelerate the pace ?

The completed code is in part2 branch

⭐⭐⭐ The repo here

Demo site

✌️✌️✌️ Talk to you in part 3, bye for now.

Discussion (0)