How to make goUp and goDown functions work in .jsx file?

Viewed 21

I have a goUp and goDown functions that doesn't work in a .jsx file. There's a textarea and two buttons (up and down). Using the buttons the functions should scroll up and scroll down in the textarea. I tested the same code in a .js file and they worked fine. However in a .jsx file they didn't work at all. I did some research, but I couldn't figure out the problem.

import { useState } from 'react'
import Dialog from '@mui/material/Dialog'
import Button from '@mui/material/Button'
import CircularProgress from '@mui/material/CircularProgress'
import CloseIcon from '@mui/icons-material/Close'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'
import { styled } from '@mui/material/styles'
import { UpdateBookModalForm } from './updateBookModalSkin'
import { updateBook } from 'api/book'
import Toast from 'shared/Toast'
import { queryClient } from 'App'
import AppContainer from '../../appSkin.js'


const UpdateBookModal = ({
    book_id,
    book_title,
    book_author,
    book_issn,
    book_note,
    handleClose,
    modalOpen,
}) => {
    const okayy = document.getElementById("textt");

    const [bookTitle, setBookTitle] = useState()
    const [author, setAuthor] = useState()
    const [issn, setIssn] = useState()
    const [note, setNote] = useState()
    const [bookUpdating, setBookUpdating] = useState(false)
    const [toastMessage, setToastMessage] = useState('')
    const [toastType, setToastType] = useState('')
    const [toastOpen, setToastOpen] = useState(false)

    const goUp = (id) => {
        if (id.scrollTop !== 0) {
            id.scrollTo({
                top: id.scrollTop - 10,
                left: 0,
                behavior: "smooth"
            });
        }
    };
    const goDown = (id) => {
        id.scrollTo({
            top: id.scrollTop + 10,
            left: 0,
            behavior: "smooth"
        });
    };

    const handleSubmit = async ev => {
        ev.preventDefault()

        setBookUpdating(true)

        const result = await updateBook(book_id, {
            book_title: bookTitle,
            book_author: author,
            book_issnisbn: issn,
            book_notes: note,
        })

        setBookUpdating(false)
        handleClose()
        setToastOpen(true)

        if (result.error) {
            setToastType('error')
            if (result.error.response) {
                setToastMessage(result.error.response.data.message)
            } else if (result.error.request) {
                setToastMessage(result.error.request)
            } else {
                setToastMessage(result.error.message)
            }
        } else {
            setToastType('success')
            setToastMessage('Book updated successfully!')
            queryClient.invalidateQueries('books')
        }
    }

    const toastClose = (event, reason) => {
        if (reason === 'clickaway') {
            return
        }

        setToastOpen(false)
    }

    return (
        <BootstrapDialog
            onClose={handleClose}
            aria-labelledby="customized-dialog-title"
            open={modalOpen}
        >
            <UpdateBookModalForm onSubmit={handleSubmit}>
                <AppContainer>
                    <div className="modal_top">
                        <input
                            style={{ lineHeight: 2.5, /*paddingLeft: 15*/ }}
                            className="h8 input-box font"
                            type="text"
                            placeholder="TITLE"
                            value={bookTitle}
                            onChange={ev => setBookTitle(ev.target.value)}
                        />

                        <span className="close-icon" onClick={handleClose}>
                            <CloseIcon />
                        </span>
                    </div>

                    <div className="top" onClick={() => goUp(okayy)}>
                        <KeyboardArrowUpIcon style={{ cursor: 'pointer' }} />
                    </div>
                    <textarea
                        id="textt"
                        rows="4"
                        cols="50"
                        maxLength="400"
                        className="h8 text-box font"
                        placeholder="YOUR NOTES"
                        value={note}
                        onChange={ev => setNote(ev.target.value)}
                    />
                    <div className="bottom" onClick={() => goDown(okayy)}>
                        <KeyboardArrowDownIcon style={{ cursor: 'pointer' }} />
                    </div>

                    <div className="modal_bottom">
                        <div className='note_buttons_container'>
                            <div className="h7 note">Please note that in most cases we can retrieve <br /> Metadata directly from the uploaded file</div>
                            <div className="buttons">
                                <Button
                                    onClick={handleClose}
                                    variant="contained"
                                    className="h6 login-btn font"
                                >
                                    Cancel
                                </Button>

                                <Button
                                    type="submit"
                                    variant="contained"
                                    className="h6 login-btn"
                                    disabled={bookUpdating}
                                >
                                    {bookUpdating ? (
                                        <CircularProgress
                                            style={{ height: '28px', width: '28px' }}
                                            color="inherit"
                                        />
                                    ) : (
                                        'Save'
                                    )}
                                </Button>
                            </div>
                        </div>
                    </div>
                </AppContainer>
            </UpdateBookModalForm>

            <Toast
                toastClose={toastClose}
                open={toastOpen}
                severity={toastType}
                message={toastMessage}
            />
        </BootstrapDialog>
    )
}

export default UpdateBookModal
1 Answers

You need to use hook useRef:

  const ref = useRef<HTMLTextAreaElement>();
  const handleDown = () => {
    if (ref.current) {
      ref.current.scrollTo({
        top: ref.current.scrollTop + 10,
        left: 0,
        behavior: "smooth"
      });
    }
  };
  // .....

  <textarea ref={ref} {..otherProps} />

Here is a live example:

Edit tender-euclid-92heyb

Related