web: components: Fix re-rendering of TextInput
This commit is contained in:
parent
428fd7f075
commit
f183b2f55d
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import { Collapse, Container, Row, Col } from 'reactstrap';
|
import { Collapse, Container, Row, Col } from 'reactstrap';
|
||||||
import { storiesOf } from '@storybook/react';
|
import { storiesOf } from '@storybook/react';
|
||||||
import TextInput from '../text-input';
|
import TextInput from '../text-input';
|
||||||
@ -11,7 +11,7 @@ const LoginForm = props => {
|
|||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [passwordValid, setPasswordValid] = useState(true);
|
const [passwordValid, setPasswordValid] = useState(true);
|
||||||
|
|
||||||
const validateAndSubmit = (event) => {
|
const validateAndSubmit = useCallback((event) => {
|
||||||
if (!login.trim())
|
if (!login.trim())
|
||||||
setLoginValid(false);
|
setLoginValid(false);
|
||||||
|
|
||||||
@ -22,7 +22,17 @@ const LoginForm = props => {
|
|||||||
return onSubmit(event, { login, password });
|
return onSubmit(event, { login, password });
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
|
const onLoginChange = useCallback(event => {
|
||||||
|
setLogin(event.target.value);
|
||||||
|
setLoginValid(true);
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onPasswordChange = useCallback(event => {
|
||||||
|
setPassword(event.target.value);
|
||||||
|
setPasswordValid(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
@ -38,10 +48,7 @@ const LoginForm = props => {
|
|||||||
scale={true}
|
scale={true}
|
||||||
isAutoFocussed={true}
|
isAutoFocussed={true}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
onChange={event => {
|
onChange={onLoginChange} />
|
||||||
setLogin(event.target.value);
|
|
||||||
setLoginValid(true);
|
|
||||||
}} />
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{ margin: "23px 0 0" }}>
|
<Row style={{ margin: "23px 0 0" }}>
|
||||||
@ -56,10 +63,8 @@ const LoginForm = props => {
|
|||||||
size='huge'
|
size='huge'
|
||||||
scale={true}
|
scale={true}
|
||||||
tabIndex={2}
|
tabIndex={2}
|
||||||
onChange={event => {
|
onChange={onPasswordChange}
|
||||||
setPassword(event.target.value);
|
/>
|
||||||
setPasswordValid(true);
|
|
||||||
}} />
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{ margin: "23px 0 0" }}>
|
<Row style={{ margin: "23px 0 0" }}>
|
||||||
|
@ -3,9 +3,14 @@ import PropTypes from 'prop-types'
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import commonInputStyle from '../text-input/common-input-styles';
|
import commonInputStyle from '../text-input/common-input-styles';
|
||||||
import MaskedInput from 'react-text-mask'
|
import MaskedInput from 'react-text-mask'
|
||||||
|
import isEqual from "lodash/isEqual";
|
||||||
|
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
/* eslint-disable react/prop-types */
|
||||||
const Input = ({ isAutoFocussed, isDisabled, isReadOnly, hasError, hasWarning, scale, withBorder, keepCharPositions, ...props }) =>
|
const Input = ({ isAutoFocussed, isDisabled, isReadOnly, hasError, hasWarning, scale, withBorder, keepCharPositions, ...props }) =>
|
||||||
(props.mask != null) ? <MaskedInput keepCharPositions {...props}/> : <input {...props}/>;
|
(props.mask != null) ? <MaskedInput keepCharPositions {...props}/> : <input {...props}/>;
|
||||||
|
/* eslint-enable react/prop-types */
|
||||||
|
/* eslint-enable no-unused-vars */
|
||||||
|
|
||||||
const StyledInput = styled(Input).attrs((props) => ({
|
const StyledInput = styled(Input).attrs((props) => ({
|
||||||
id: props.id,
|
id: props.id,
|
||||||
@ -75,9 +80,15 @@ const StyledInput = styled(Input).attrs((props) => ({
|
|||||||
${props => !props.withBorder && `border: none;`}
|
${props => !props.withBorder && `border: none;`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const TextInput = props => {
|
class TextInput extends React.Component {
|
||||||
//console.log("TextInput render");
|
shouldComponentUpdate(nextProps) {
|
||||||
return (<StyledInput {...props} />);
|
return !isEqual(this.props, nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// console.log(`TextInput render id=${this.props.id}`);
|
||||||
|
return (<StyledInput {...this.props} />);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextInput.propTypes = {
|
TextInput.propTypes = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount, shallow } from 'enzyme';
|
||||||
import TextInput from '.';
|
import TextInput from '.';
|
||||||
|
|
||||||
describe('<TextInput />', () => {
|
describe('<TextInput />', () => {
|
||||||
@ -10,4 +10,27 @@ describe('<TextInput />', () => {
|
|||||||
|
|
||||||
expect(wrapper).toExist();
|
expect(wrapper).toExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('not re-render test', () => {
|
||||||
|
const onChange= event => alert(event.target.value);
|
||||||
|
|
||||||
|
const wrapper = shallow(<TextInput value="text" onChange={onChange} />).instance();
|
||||||
|
|
||||||
|
const shouldUpdate = wrapper.shouldComponentUpdate(wrapper.props);
|
||||||
|
|
||||||
|
expect(shouldUpdate).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('re-render test by value', () => {
|
||||||
|
const onChange= event => alert(event.target.value);
|
||||||
|
|
||||||
|
const wrapper = shallow(<TextInput value="text" onChange={onChange} />).instance();
|
||||||
|
|
||||||
|
const shouldUpdate = wrapper.shouldComponentUpdate({
|
||||||
|
...wrapper.props,
|
||||||
|
value: "another text"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(shouldUpdate).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user