Students who have studied React philosophy should know that when we think about how to split components, we should fully analyze the interactive characteristics, structural characteristics, and data characteristics of the current page/component to judge how the current page should be split with the purpose of simplifying the code.
In the previous article, we implemented the addition, deletion, modification and search of the task list without thinking about splitting. But the result is that the code is relatively complex and not concise. Therefore, based on the splitting basis mentioned above, we can split the page into the following three steps
<header /> <List /> <Addition />
If you are still confused about the result of this split, it is recommended to review our React philosophy based on live replay.
OK, the next step is to analyze how to implement it.
The header part is just a simple structure and style, without additional functions, and is relatively simple, so we don’t need to consider this part too much.
The List component is a list. Obviously, it requires an array to be passed from outside as a data source. In addition, it also has delete and modify operations inside it. The data source is passed from outside, so we need to provide two methods to allow external responses to delete and modify operations within the internal response.
Therefore, the props type declaration of the List component is as follows
import {Job} from './index' interface ListProps { list: Job[], onRemove: (i: number) => any, onEditor: (i: number, value: Job) => any }
After clarifying List props, its encapsulation code will be easy to write
import {Job} from './index' interface ListProps { list: Job[], onRemove: (i: number) => any, onEditor: (i: number, value: Job) => any } export default function List(props: ListProps) { const {list, onRemove, onEditor} = props function troggleSelected(i: number) { const job = list[i] onEditor(i, { ...job, isSelected: ! }) } return ( <div className="container"> <div className="task-header"> <div className="title">Ongoing tasks</div> <div className="right">...</div> </div> {((job, i) => ( <div className="job-wrapper" key={}> <div className="selected" onClick={() => troggleSelected(i)}> { && <div className="circle"></div>} </div> <div className="desc">{}</div> <div className="remove" onClick={() => onRemove(i)}>delete</div> </div> ))} </div> ) }
The thinking of the Addition component is a little more complicated.
The interactive behavior of editing pop-ups is the internal behavior of Addition, so controlling it to display hidden data can also be internal data. To the outside, you only need to provide a hook function when adding it, and pass the internal data to the parent level.
Such a statement is inevitably a bit boring, and it is more appropriate to understand it in combination with the code.
The code is as follows:
import { useEffect, useRef, useState } from 'react'; import { randomId } from '../../utils'; import {Job} from './index' interface AdditionProps { onAdd: (job: Job) => any } export default function Addition(props: AdditionProps) { const [desc, setDesc] = useState('') const [show, setShow] = useState(false) const inputRef = useRef<HTMLInputElement>(null) const {onAdd} = props useEffect(() => { if (show) { ?.focus() } }, [show]) function add() { onAdd({ id: randomId(), desc, isSelected: false, createTime: () }) } return ( <> {show ? ( <div className="dialog"> <input onChange={event => setDesc()} ref={inputRef} placeholder="Please enter a task description" onBlur={() => {setTimeout(() => { setShow(false) }, 0)}} /> <div className="create" onClick={add}>create</div> </div> ) : <div className="add" onClick={() => setShow(true)}>New</div>} </> ) }
In this way, our main logic becomes very simple, and only one need to be maintained on the datajobs
Just do it.
import { useState } from 'react'; import logo from './'; import Addition from './Addition' import List from './List' import './'; export interface Job { desc: string, id: string, createTime: number, isSelected: boolean } function App() { const [jobs, setJobs] = useState<Array<Job>>([]) function remove(i: number) { (i, 1) setJobs([...jobs]) } function editor(i: number, job: Job) { jobs[i] = job setJobs([...jobs]) } return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>React Knowing the Realm</h1> </header> <List list={jobs} onRemove={remove} onEditor={editor} /> <Addition onAdd={(job) => setJobs([...jobs, job])} /> </div> ); } export default App;
Component splitting is a process of simplifying code. In this process, we eliminate all the interference factors in the main logic, making the main code very concise and greatly improving maintainability.
Component splitting is a soft skill that requires us to constantly accumulate and think. It is the core part that determines the quality of your code.
This is the end of this article about how to split components in React. For more related content on splitting components, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!