redux 限制onChange触发器的数量

xghobddn  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(140)

我有一个带有textarea的组件,我从Redux商店将value设置为{store.some_property}。我的意图是通过在textarea上使用onChange事件调度一个动作来更新商店。然而,问题是使用onChange每次按下一个键都会触发一个动作。我正在寻找一种方法来限制这些触发器的数量。我相信这个问题是一个通用的组件,不一定需要代码。然而,这里是我的组件,其中只有一个textarea,所以如果你需要参考,这里是:

import React, { useEffect } from 'react'
import Tab from 'react-bootstrap/Tab'
import Tabs from 'react-bootstrap/Tabs'
import { useParams } from 'react-router-dom'
import { RootState } from '../store/reducers/store'
import { useDispatch, useSelector } from 'react-redux'
import * as documentActions from '../store/actions/documents'
import * as translationActions from '../store/actions/translations'
import TranslationLine from '../components/translation/TranslationLine'
const organizeText = (inputText: string) => {
    // Step 1: Combine all lines together
    let combinedText = inputText.replace(/\s+/g, ' ').trim()

    // Step 2: Remove dashes and combine the words around the dash
    combinedText = combinedText.replace(/‐ /g, '')

    // Step 3: Separate the lines using dots
    const lines = combinedText.split('.').map((line) => line.trim())
    const processedText = lines.join('.\n')

    return processedText
}

const Translation = () => {
    const params = useParams()
    const dispatch = useDispatch()
    const pageID: string = params.page || ''
    const page = useSelector((state: RootState) => state.documents.curDocument.pages[pageID])
    const translations = useSelector((state: RootState) => state.translations)
    useEffect(() => {
        if (!page) {
            dispatch(documentActions.getPageDetails(pageID))
        }
        if (page?.best_transcription) {
            dispatch(translationActions.setDefaultTranslationText(page))
        }
    }, [dispatch, page, pageID])

    const handleOrganizeButton = () => {
        const organizedText = organizeText(translations.copticTextForTranslation)
        dispatch(translationActions.setOrganizedTranslationText(organizedText))
    }
    const handleResetButton = () => {
        dispatch(translationActions.setDefaultTranslationText(page))
    }
    const handleTextChange = () => {
        const textarea = document.getElementById('copticTextarea') as HTMLTextAreaElement
        const textareaValue = textarea.value
        dispatch(translationActions.setOrganizedTranslationText(textareaValue))
    }
    return (
        <Tabs defaultActiveKey="organizeText" id="uncontrolled-tab-example" className="mb-3">
            <Tab eventKey="organizeText" title="Text organization">
                {translations && (
                    <>
                        <div className="container">
                            <textarea
                                id={'copticTextarea'}
                                className="form-control fs-4"
                                rows={8}
                                value={translations.copticTextForTranslation}
                                onChange={() => handleTextChange()}
                            />
                        </div>
                        <div className="d-flex justify-content-center my-3">
                            <button className="btn btn-success me-3" onClick={() => handleOrganizeButton()}>
                                Organize text
                            </button>
                            <button className="btn btn-danger" onClick={() => handleResetButton()}>
                                Reset text
                            </button>
                        </div>
                    </>
                )}
            </Tab>
            <Tab eventKey="translation" title="Translation">
                <div className="container">
                    {translations.copticTextForTranslation.split('\n').map((line, index) => (
                        <TranslationLine key={index} originalText={line} />
                    ))}
                </div>
            </Tab>
        </Tabs>
    )
}

export default Translation

字符串

bvn4nwqk

bvn4nwqk1#

你可以使用一种叫做“debounce”的技术。检查Lodash Debounce来实现一个debounce函数。一个debounce函数只有在它上次被调用后经过了一定的时间间隔后才被执行。但是,由于你使用redux状态作为textarea的值,只有在用户停止键入并执行去抖动函数后,他们才能在textarea元素中看到更新的值。元素

import debounce from 'lodash.debounce';

const handleTextChange = (e) => {
    const textareaValue = e.target.value
    dispatch(translationActions.setOrganizedTranslationText(textareaValue))
}

const debouncedHandleTextChange = debounce(handleTextChange, 500);

字符串
不受控制的Textarea元素:

<div className="container">
    <textarea
       id={'copticTextarea'}
       className="form-control fs-4"
       rows={8}
       onChange={debouncedHandleTextChange}
       defaultValue={translations.copticTextForTranslation}
     />
</div>


请查看此演示codesandbox以供参考。

相关问题