React笔记

React

问题汇总

在forwardRef中使用ref

解决方案:自定义hook

export const assignRefs = (...refs) => {
    return (node) => {
        refs.forEach((r) => {
            if (typeof r === "function") {
                r(node);
            } else if (r) {
                r.current = node;
            }
        });
    };
};

composition事件导致中文输入法有问题

React中文输入法问题

react,因为输入法会劫持内容,导致和 React 不同步

解决方案:自定义组件,然后对 composition 事件进行监听。如果是输入法控制时,不做转换,当输入法输入结束时再进行转换

import React, {useState, useEffect, forwardRef, useRef} from 'react';
import {Input} from 'antd';
import {assignRefs} from './custom_hook'

const App = forwardRef((props, ref) => {
    const {
        onChange,
        value,
        onBlur,
        onPressEnter,
        rows
    } = props;
    const inputRef = useRef();
    const lock = useRef(false);
    const [currentValue, setCurrentValue] = useState(value);

    useEffect(() => {
        setCurrentValue(value)
    }, [value]);

    const handleCompositionStart = (event) => {
        lock.current = true;
    }

    const handleCompositionEnd = (event) => {
        onChange(event)
        lock.current = false;
    }

    const onInputChange = (event) => {
        setCurrentValue(event.target.value)
        if (lock.current) {
            return
        }
        onChange(event)
    }

    useEffect(() => {
        inputRef.current.resizableTextArea.textArea.addEventListener('compositionstart', handleCompositionStart);
        inputRef.current.resizableTextArea.textArea.addEventListener('compositionend', handleCompositionEnd);
        return () => {
            inputRef.current && inputRef.current.resizableTextArea.textArea.removeEventListener('compositionstart', handleCompositionStart);
            inputRef.current && inputRef.current.resizableTextArea.textArea.removeEventListener('compositionend', handleCompositionEnd);
        }
    }, [])
    return (
        <Input.TextArea value={currentValue} ref={assignRefs(inputRef, ref)} onBlur={onBlur}
                        onChange={onInputChange}
                        onPressEnter={onPressEnter}
                        rows={rows}/>
    );
});
export default App;