Kishieel
Kishieel

Reputation: 2053

React Redux - very slow onChange

I have table of employees with theirs data. Under last row is one another only with input to add new employee - I need set only name, other properties are set default and can be change letter. Input should call dispatch only if I press enter. My onChange handler took about 80ms when is only one object in array, when is 20 objects the same handler tooks about 2000ms. What is wrong with this:

store/index.js:

const reducer = (state = {}, action) => {
    return {
        default: defaultReducer(state.default, action, state),
        // [ 3 other reducers]
        employees: employeesReducer(state.employees, action),
    };
};
const store = createStore(reducer);

I can't use combineReducers because I need one reducer which access to whole store. This reducer ( default ) is used to save/load store as json data. However my custom combine reducer is't the reason because I tried also with normal combineReducers without my default reducer. Nothing change still 2000 ms for onChange.

reducers/employees.js

const initialState = { }
let next_employee_id = 1;

const employeesReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'EMPLOYEE_CREATE': {
            return {
                 ...state,
                 [ next_employee_id++ ]: {
                     signature: action.value,
                     time_contract: 1,
                     role: 'PRACOWNIK'
                 }
             }
        }
        // [ other cases - update, remove etc ]
        default:
             return state
    }

components/EmployeeManager.js ( only the part responsible for adding )

<Form.Control 
    type="text" 
    size="sm" 
    placeholder="ADD EMPLOYEE" 
    onKeyDown={ (e) => { 
        ( e.key === 'Enter' ) ? 
        ( () => { 
            dispatch({ type: 'EMPLOYEE_CREATE', value: e.target.value }); 
            e.target.value = ""; 
         })() : 
         (() => {})() 
    } 
}/>

It isn't re-rendering fault. I check it. Re-rendering take about 8ms with one employee and about 10ms with 100 employees.

react version : 16.13.1

react-redux version: 7.2.0

I also use react-bootstrap ( version : 1.0.1 ) but I don't think it's have any affects.


EDIT NO.1

In my EmployeeManager component I have Modal from react-bootstrap. When I click on employee row I can edit him in the Modal. It's look like this:

const EmployeeManager = React.memo( () => {
    const Schedule = React.memo(() => {
    const [modalShow, setModalShow] = useState(false);
    const [modalEmployeeKey, setModalEmployeeKey] = useState(0)
    const dispatch = useDispatch();
    const employees = useSelector( state => state.employees );

    return ( <>
        <Modal show={ modalShow } onHide={ () => setModalShow(false) } size="lg">
            <Modal.Body>
                <Container>
                    <Row className="show-grid align-items-center mb-2">
                        <Col sm={6} lg={8}> Dane personalne: </Col>
                        <Col sm={6} lg={4}>
                            <Form.Control type="text" value={ employees[ modalEmployeeKey ]?.signature } onChange={ (e) => dispatch({ type: 'EMPLOYEE_UPDATE', id: modalEmployeeKey, field: 'signature', value: e.target.value })}/>
                        </Col>
                    </Row>
                    { /* other rows */ }
                </Container>
            </Modal.Body>
        </Modal>
        { /* Other thinks */ }
    </> )
})

Variable employess look like this :

{
    1: { signature: "ADAM NOWAK", time_contract:1, /* etc. */ },
    /* other */ 
}

If I remove Modal from component everything start work correctly. Whats wrong ?!


EDIT NO.2

If I remove Modal from component everything start work correctly.

Not exactly.. after about 60 employess work slow again :C

Upvotes: 2

Views: 639

Answers (1)

costal oktopus
costal oktopus

Reputation: 329

Try to Memo the component.

function list({ props }){
 return(
  <>
   {props.map((item)=>{
    return <Item />
   })}
  </>
 )
}

function Item memo((){
 return
  <></>
})

Upvotes: 1

Related Questions