Giter Club home page Giter Club logo

Comments (5)

jacargentina avatar jacargentina commented on June 6, 2024 1

Got it

// @flow
import React, { useContext, useState, useEffect } from 'react';
import TextArea from 'semantic-ui-react/dist/commonjs/addons/TextArea';
import { EditContext } from './EditContext';
import SongViewFrame from './SongViewFrame';
import { useDebouncedCallback } from 'use-debounce';

const SongEditor = () => {
  const edit = useContext(EditContext);
  const { editSong, text, setText, setHasChanges, songFile } = edit;
  const [debouncedText, setDebouncedText] = useState(text);
  const [callback, cancel, callPending] = useDebouncedCallback(
    text => setDebouncedText(text),
    800
  );

  useEffect(() => {
    if (editSong) {
      callback(text);
      callPending();
    }
  }, [editSong]);

  if (!editSong) {
    return null;
  }

  return (
    <div
      style={{
        flex: 1,
        display: 'flex',
        flexDirection: 'row',
        overflow: 'auto',
        padding: 10
      }}>
      <TextArea
        style={{
          fontFamily: 'monospace',
          backgroundColor: '#fcfcfc',
          width: '50%',
          outline: 'none',
          resize: 'none',
          border: 0,
          padding: '10px 20px',
          overflowY: 'scroll'
        }}
        value={text}
        onChange={(e, data) => {
          setHasChanges(true);
          setText(data.value);
          callback(data.value);
        }}
      />
      <div
        style={{
          width: '50%',
          overflowY: 'scroll',
          fontFamily: 'Franklin Gothic Medium',
          padding: '10px 20px'
        }}>
        <SongViewFrame
          title={songFile && songFile.titulo}
          source={songFile && songFile.fuente}
          text={debouncedText}
        />
      </div>
    </div>
  );
};

export default SongEditor;

Thanks a LOT!

from use-debounce.

xnimorz avatar xnimorz commented on June 6, 2024

Hello, @jacargentina .
useDebounce receives the initial value during the first render. I mean, if you make such example:

function Song({text}) {
  const [debouncedText] = useDebounce(text, 800);
  return debouncedText;
}

ReactDOM.render(<Song text="Hello" />, root);

It would render "Hello" without the 800ms timeout.
You can see it in the example: https://codesandbox.io/s/kx75xzyrq7 where the debounced value "Hello" would be rendered within the first render.
Or in the unit tests: https://github.com/xnimorz/use-debounce/blob/master/test/cache.test.js#L15

So, as I understand, your use case is:

  1. You render SongEditor
  2. Then User clicked to the song
  3. SongEditor receives new data, and debounce timeout is started.
  4. After 800ms the text will be updated.

If you want to remove the excess timeout at the fourth step, you can:

Use the specific useDebounceCallback method as it allows to call callPending:

import { useDebouncedCallback } from 'use-debounce';

const SongEditor = () => {
  const edit = useContext(EditContext);
  const { editSong, text, setText, setHasChanges, songFile, editSongId } = edit;
  const [ debouncedText, setDebouncedText ] = useState(text);
  const [ debouncedCallback, , callPending] = useDebounceCallback((e) => {setDebouncedText(e.target.value)}, 800);
  
  useEffect(() => {
    callPending();
  }, [editSongId]);

  if (!editSong) {
    return null;
  }

  return <div> .... {debouncedText} </div>

In this example:

  1. I changed useDebounce to useDebounceCallback.
  2. Added editSongId to the EditContext. Maybe you already have a similar thing. The idea is to call debouncedCallback immediately when the song id is changed
  3. Added useEffect, to call callPending.

Moreover, there is another way to solve your task. You can add the key to the SongEditor, that would represent the id of the song. Like this:

<SongEditor key={editSongId} />

In this solution, react will recreate the SongEditor component from the scratch every time when user changes the song to edit.

from use-debounce.

jacargentina avatar jacargentina commented on June 6, 2024

Mmmm it is not working, as i dont clearly understand the new code.

I'm posting my fill working example.

// @flow
import React, { useContext } from 'react';
import TextArea from 'semantic-ui-react/dist/commonjs/addons/TextArea';
import { EditContext } from './EditContext';
import SongViewFrame from './SongViewFrame';
import { useDebounce } from 'use-debounce';

const SongEditor = () => {
  const edit = useContext(EditContext);
  const { editSong, text, setText, setHasChanges, songFile } = edit;
  const [debouncedText] = useDebounce(text, 800);

  if (!editSong) {
    return null;
  }

  return (
    <div
      style={{
        flex: 1,
        display: 'flex',
        flexDirection: 'row',
        overflow: 'auto',
        padding: 10
      }}>
      <TextArea
        style={{
          fontFamily: 'monospace',
          backgroundColor: '#fcfcfc',
          width: '50%',
          outline: 'none',
          resize: 'none',
          border: 0,
          padding: '10px 20px',
          overflowY: 'scroll'
        }}
        value={text}
        onChange={(e, data) => {
          setHasChanges(true);
          setText(data.value);
        }}
      />
      <div
        style={{
          width: '50%',
          overflowY: 'scroll',
          fontFamily: 'Franklin Gothic Medium',
          padding: '10px 20px'
        }}>
        <SongViewFrame
          title={songFile && songFile.titulo}
          source={songFile && songFile.fuente}
          text={debouncedText}
        />
      </div>
    </div>
  );
};

export default SongEditor;

I should note:

  1. My editSongId is inexistent; i use the editSong object directly from the context (It is provided when the user loads a song)
  2. Yes, SongEditor is rendered, but returns null when there is not current song (editSong)

from use-debounce.

xnimorz avatar xnimorz commented on June 6, 2024

Yes, SongEditor is rendered, but returns null when there is not current song (editSong)

It means the first value of useDebounce would be ''

Ok. According to the full example, can you specify the fields of the editSong object? I think I can give you a more accurate answer if I recognize the structure.

Without the additional information, I can suggest trying such code:

import React, { useContext, useState } from 'react';
import TextArea from 'semantic-ui-react/dist/commonjs/addons/TextArea';
import { EditContext } from './EditContext';
import SongViewFrame from './SongViewFrame';
import { useDebounceCallback } from 'use-debounce';

const SongEditor = () => {
  const edit = useContext(EditContext);
  const { editSong, text, setText, setHasChanges, songFile } = edit;
  const [debouncedText, setDebouncedText] = useState(text);
  const [callback, cancel, callPending] = useDebounceCallback((text) => setDebouncedText(text), 800);

  useEffect(() => {
    callPending();
  }, [songFile]);

  if (!editSong) {
    return null;
  }

  return (
    <div
      style={{
        flex: 1,
        display: 'flex',
        flexDirection: 'row',
        overflow: 'auto',
        padding: 10,
      }}
    >
      <TextArea
        style={{
          fontFamily: 'monospace',
          backgroundColor: '#fcfcfc',
          width: '50%',
          outline: 'none',
          resize: 'none',
          border: 0,
          padding: '10px 20px',
          overflowY: 'scroll',
        }}
        value={text}
        onChange={(e, data) => {
          setHasChanges(true);
          setText(data.value);
          callback(data.value);
        }}
      />
      <div
        style={{
          width: '50%',
          overflowY: 'scroll',
          fontFamily: 'Franklin Gothic Medium',
          padding: '10px 20px',
        }}
      >
        <SongViewFrame title={songFile && songFile.titulo} source={songFile && songFile.fuente} text={debouncedText} />
      </div>
    </div>
  );
};

export default SongEditor;

from use-debounce.

xnimorz avatar xnimorz commented on June 6, 2024

You are welcome!

from use-debounce.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.