Ad

React State Update Only Re-rendering On Second Click - Async Data

- 1 answer

I'm attempting to update this component when the path changes and updates the filesList state.

However, the component only updates if I click a second time due to useState being aysnc.

What would be the best method of updating this state such that it re-renders the component with the new folders from dropbox which is stored in filesList with one click?

pathUpdateHandler is being used to get the path of the folder clicked on and then change the path which is used in the post request to update the path state.

const DropBoxChooser = props => {
    const [filesList, setFilesList] = useState([]);
    const [thumbBase64, setThumbBase64] = useState([]);
    const [loader, setLoader] = useState(false);
    const [previewImage, setPreviewImage] = useState("/Customers");
    const [path, setPath] = useState('/customers');

    const requestConfig = {
        headers: {
            Authorization: `Bearer ${config.dropbox_api_key}`,
            'Content-Type': 'application/json',
        },
    };

    const previewRequestConfig = {
        headers: {
            Authorization: `Bearer ${config.dropbox_api_key}`,
            'Content-Type': 'application/octet-stream',
            'Dropbox-API-Arg': `{"path": "${previewImage}"}`
        },
    };

    useEffect(() => {
        console.log(path);
    }, [path])

    const loadimages = () => {
        setLoader(true);
        axios.post('https://api.dropboxapi.com/2/files/list_folder', {path}, requestConfig)
        .then(res => {
            setFilesList(res.data.entries);
            setLoader(false);
        });
    }

    const viewableFile = () => {
        console.log(Object.values(filesList).indexOf('file') > -1 ? 'true' : 'false');
        // let thumbs = {
        //     entries: []
        // };

        // filesList.forEach(path => {
        //     thumbs.entries.push({path: path.path_lower})
        // });
        // setThumbList(thumbs);

        // axios.post('https://content.dropboxapi.com/2/files/get_thumbnail_batch', thumbList, requestConfig)
        // .then(res => {
        //     setThumbBase64(res.data.entries)
        // });
    }

    const pathUpdateHandler = (customerPath) => {
        setPath(customerPath);
        console.log(path);
        axios.post('https://api.dropboxapi.com/2/files/list_folder', {path}, requestConfig)
        .then(res => {
            setFilesList(res.data.entries);
            setLoader(false);
            viewableFile();
            console.log(filesList);
        })
    }

    const getImagePreview = () => {
        axios.post('https://content.dropboxapi.com/2/files/get_preview', null, previewRequestConfig)
        .then(res => setPreviewImage(res.data))
    }

    return (
        <Fragment>
            <div>
                <Button onClick={loadimages}>Click Me!</Button>
                {loader === true ?
                    <h1>Loading...</h1>
                :
                filesList.map((customer) => (
                    <Button onClick={customer['.tag'] === 'folder' ?
                        () => {
                            pathUpdateHandler(customer.path_lower)
                        } : null}
                    >
                        {customer['.tag'] === 'file'
                            ? thumbBase64.map(item =>
                                <img
                                    src={`data:image/jpeg+xml;base64,${item.thumbnail}`}
                                    alt="" onClick={getImagePreview}
                                />)
                            : null
                        }
                        {customer.name}
                    </Button>
                ))}
            </div>
        </Fragment>
    )
}

export default DropBoxChooser;

Thanks!

Ad

Answer

You should pass cutomerPath to api call

const pathUpdateHandler = customerPath => {
  setPath(customerPath);
  console.log(path);
  axios
    .post(
      "https://api.dropboxapi.com/2/files/list_folder",
      { customerPath },
      requestConfig
    )
    .then(res => {
      setFilesList(res.data.entries);
      setLoader(false);
      viewableFile();
      console.log(filesList);
    });
};
Ad
source: stackoverflow.com
Ad