react-use#useUpdateEffect JavaScript Examples
The following examples show how to use
react-use#useUpdateEffect.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useStickySWR.js From covid19india-react with MIT License | 6 votes |
export function useStickySWR(key, fetcher, swrOptions, ...args) {
const [options, setOptions] = useState(swrOptions);
const {data, isValidating, error, ...rest} = useSWR(
key,
fetcher,
options,
...args
);
useUpdateEffect(() => {
setOptions(
produce(options, (draftOptions) => {
draftOptions.initialData = data;
})
);
}, [data]);
return {
...rest,
isValidating,
error,
data,
};
}
Example #2
Source File: index.jsx From botble-graphql-next with MIT License | 5 votes |
Header = () => {
const router = useRouter();
const [toggle, toggleOpen] = useToggle(false);
const isMobile = useMedia('(max-width: 700px)');
useUpdateEffect(() => {
if (isMobile) {
toggleOpen(false);
}
}, [isMobile, router.asPath]);
return (
<header>
<div className="container container-fluid px-2 lg:px-0">
<div className="flex justify-between py-3 sm:py-6 select-none">
<h1 className="text-3xl text-gray-700 font-semibold">
<Link href="/">
<a className="hover:no-underline">
<span className="text-fresh-red">Tôi yêu</span> lập trình
</a>
</Link>
</h1>
<div className="flex items-center">
{!isMobile && <Navigation />}
<div className="flex ml-10 items-center">
<Icon icon={iconSearchIcon} className="font-bold" height="18" />
{isMobile && (
<Icon
icon={toggle ? closeBig : menuIcon}
className="cursor-pointer ml-2 font-bold"
width="18"
height="16"
onClick={toggleOpen}
/>
)}
</div>
</div>
</div>
{isMobile && toggle && <Navigation wide />}
</div>
</header>
);
}
Example #3
Source File: Search.js From covid19india-react with MIT License | 4 votes |
function Search() {
const [searchValue, setSearchValue] = useState('');
const [expand, setExpand] = useState(false);
const [results, setResults] = useState([]);
const searchInput = useRef(null);
const {t} = useTranslation();
const [engine, setEngine] = useState(null);
const [districtEngine, setDistrictEngine] = useState(null);
useUpdateEffect(() => {
import('corejs-typeahead').then((Bloodhound) => {
setEngine(
// eslint-disable-next-line
new Bloodhound.default({
initialize: true,
local: STATE_CODES_ARRAY.filter(
({code}) => code !== UNASSIGNED_STATE_CODE
),
queryTokenizer: Bloodhound.default.tokenizers.whitespace,
datumTokenizer: Bloodhound.default.tokenizers.obj.whitespace('name'),
})
);
setDistrictEngine(
// eslint-disable-next-line
new Bloodhound.default({
initialize: true,
limit: 5,
queryTokenizer: Bloodhound.default.tokenizers.whitespace,
datumTokenizer:
Bloodhound.default.tokenizers.obj.whitespace('district'),
indexRemote: true,
remote: {
url: `${API_DOMAIN}/state_district_wise.json`,
transform: function (response) {
const districts = [];
Object.keys(response)
.filter((stateName) => stateName !== 'State Unassigned')
.map((stateName) => {
const districtData = response[stateName].districtData;
Object.keys(districtData)
.filter(
(districtName) => districtName !== UNKNOWN_DISTRICT_KEY
)
.map((districtName) => {
return districts.push({
district: districtName,
state: stateName,
});
});
return null;
});
return districts;
},
},
})
);
});
}, [expand]);
const handleSearch = useCallback(
(searchInput) => {
if (!engine) return null;
const results = [];
const sync = (datums) => {
datums.map((result, index) => {
const stateObj = {
name: result.name,
type: 'state',
route: result.code,
};
results.push(stateObj);
return null;
});
};
const districtSync = (datums) => {
datums.slice(0, 3).map((result, index) => {
const districtObj = {
name: result.district,
type: 'district',
route: STATE_CODES[result.state],
};
results.push(districtObj);
return null;
});
setResults([...results]);
};
engine.search(searchInput, sync);
districtEngine.search(searchInput, districtSync);
},
[districtEngine, engine]
);
useDebounce(
() => {
if (searchValue) {
handleSearch(searchValue);
} else {
setResults(
produce(results, (draftResults) => {
draftResults.splice(0);
})
);
}
},
100,
[searchValue]
);
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(
prototype,
'value'
).set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
const fillPlaceholder = useCallback(
(target, index, cursorPosition, callback) => {
if (expand) {
target.textContent = '';
return true;
}
const text = t(suggestions[index]);
const placeholder = target.textContent;
target.classList.remove('disappear');
target.textContent = placeholder + text[cursorPosition];
if (cursorPosition < text.length - 1) {
setTimeout(function () {
fillPlaceholder(target, index, cursorPosition + 1, callback);
}, 200);
return true;
}
callback();
},
[expand, t]
);
const clearPlaceholder = useCallback((target, callback) => {
const placeholder = target.textContent;
target.classList.add('disappear');
if (placeholder.length > 0) {
setTimeout(function () {
target.textContent = '';
clearPlaceholder(target, callback);
}, 1000);
return true;
}
callback();
}, []);
const loopThroughSuggestions = useCallback(
(target, index) => {
if (expand) {
target.textContent = '';
return true;
}
fillPlaceholder(target, index, 0, function () {
setTimeout(function () {
clearPlaceholder(target, function () {
loopThroughSuggestions(target, (index + 1) % suggestions.length);
});
}, 2000);
});
},
[clearPlaceholder, expand, fillPlaceholder]
);
useEffect(() => {
if (!expand) {
const targetInput =
document.getElementsByClassName('search-placeholder')[0];
if (targetInput) {
loopThroughSuggestions(targetInput, 0);
}
}
}, [expand, loopThroughSuggestions]);
const trail = useMemo(() => {
const styles = [];
[0, 0, 0].map((element, index) => {
styles.push({
animationDelay: `${index * 250}ms`,
});
return null;
});
return styles;
}, []);
const handleClose = useCallback(() => {
setSearchValue('');
setResults([]);
}, []);
const handleChange = useCallback((event) => {
setSearchValue(event.target.value);
}, []);
useKeyPressEvent('/', () => {
searchInput.current.focus();
});
useKeyPressEvent('Escape', () => {
handleClose();
searchInput.current.blur();
});
return (
<div className="Search">
<label className="fadeInUp" style={trail[0]}>
{t('Search your district or state')}
</label>
<div className="line fadeInUp" style={trail[1]}></div>
<div className="search-input-wrapper fadeInUp" style={trail[2]}>
<input
type="text"
value={searchValue}
ref={searchInput}
onFocus={setExpand.bind(this, true)}
onBlur={setExpand.bind(this, false)}
onChange={handleChange}
/>
{!expand && searchValue === '' && (
<span className="search-placeholder"></span>
)}
<div className={`search-button`}>
<Icon.Search />
</div>
{searchValue.length > 0 && (
<div className={`close-button`} onClick={handleClose}>
<Icon.X />
</div>
)}
</div>
{results.length > 0 && (
<div className="results">
{results.map((result, index) => (
<Link key={index} to={`state/${result.route}`}>
<div className="result">
<div className="result-left">
<div className="result-name">
{`${result.name}`}
{result.type === 'district' &&
`, ${STATE_NAMES[result.route]}`}
</div>
</div>
<div className="result-type">
<span>{[result.route]}</span>
<Icon.ArrowRightCircle size={14} />
</div>
</div>
</Link>
))}
</div>
)}
{expand && (
<>
<div className="expanded">
<div className="expanded-left">
<h3>{t('District')}</h3>
<div className="suggestions">
{districtSuggestions.map((suggestion, index) => (
<div className="suggestion" key={index}>
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, suggestion);
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t(suggestion)}
</h4>
</div>
))}
</div>
</div>
<div className="expanded-right">
<h3>{t('State/UT')}</h3>
<div className="suggestions">
{stateSuggestions.map((suggestion, index) => (
<div className="suggestion" key={index}>
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, suggestion);
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t(suggestion)}
</h4>
</div>
))}
</div>
</div>
</div>
</>
)}
</div>
);
}
Example #4
Source File: secret-scan-image-report.js From ThreatMapper with Apache License 2.0 | 4 votes |
SecretScanImageReport = props => {
const {
startPolling,
stopPolling,
registerPolling,
updatePollParams,
filterValues = {},
} = props;
const dispatch = useDispatch();
const [redirect, setRedirect] = useState(false);
const [link, setLink] = useState('');
const [rowCountValue, setRowCountValue] = useState(10);
const columns = [
{
Header: 'Node Type',
accessor: 'node_type',
Cell: row => {
let displayValue = row.value || 'container image';
displayValue = displayValue.replace('_', ' ');
return displayValue;
},
width: 30,
},
{
Header: 'Node',
accessor: 'node_name',
width: 90,
Cell: row => (
<div className="truncate" title={row.value}>
{row.value}
</div>
),
},
{
Header: 'Pass Status',
accessor: row =>
`${row.total_count - row.error_count}/${row.total_count} PASSED`,
Cell: ({ row, value }) => (
<div
className={
row?.original?.error_count === 0
? 'status-success'
: 'status-failed'
}
>
{value}
</div>
),
id: 'status',
},
];
useUpdateEffect(() => {
updatePollParams({
filters: filterValues,
page: 0
});
dispatch(saveImageReportTableStateAction({ pageNumber: 0 }));
}, [filterValues]);
useEffect(() => {
// pollable: register the function which needs to be polled
const { urlLocation: { search = '' } = {} } = props;
registerPolling(getSecretScanImageReport);
startPolling();
if (search.length === 0) {
// set save table page number to 0 if there is no search query
// This resets the page number if user navigates to this page for the 1st time.
// If user navigates from vulnerability details page, that sets a search query
// and the page number is not reset. it will should previous page number.
dispatch(saveImageReportTableStateAction({ pageNumber: 0 }));
}
return () => {
stopPolling();
};
}, []);
const rowClickHandler = scanId => {
setRedirect(true);
setLink(`/secret-scan/details/${encodeURIComponent(scanId)}`);
};
const tableChangeHandler = (params = {}) => {
updatePollParams(params);
};
const getSecretScanImageReport = (pollParams = {}) => {
const {
page = 0,
pageSize = 10,
globalSearchQuery,
alertPanelHistoryBound = props.alertPanelHistoryBound || {},
} = pollParams;
const tableFilters = pollParams.filters || filterValues;
const nonEmptyFilters = Object.keys(tableFilters)
.filter(key => tableFilters[key].length)
.reduce((acc, key) => {
// replacing back the dot which was removed redux-form as it considers that a nested field.
acc[[key.replace('-', '.')]] = tableFilters[key];
return acc;
}, {});
const params = {
lucene_query: globalSearchQuery,
// Conditionally adding number and time_unit fields
...(alertPanelHistoryBound.value
? { number: alertPanelHistoryBound.value.number }
: {}),
...(alertPanelHistoryBound.value
? { time_unit: alertPanelHistoryBound.value.time_unit }
: {}),
filters: nonEmptyFilters,
start_index: page ? page * pageSize : page,
size: pageSize,
};
return dispatch(getSecretScanDataAction(params));
};
const handlePageChange = pageNumber => {
tableChangeHandler({
page: pageNumber,
});
dispatch(saveImageReportTableStateAction({ pageNumber }));
};
const setRowCount = e => {
const rowCount = Number(e.target.value);
setRowCountValue(rowCount);
};
useUpdateEffect(() => {
updatePollParams({ pageSize: rowCountValue });
}, [rowCountValue]);
const renderSubComponent = ({ row }) => (
<SecretScanImageReportDetails
data={row.original.scans}
rowClickHandler={scanId => rowClickHandler(scanId)}
isToasterVisible={props.isToasterVisible}
onDelete={() => getSecretScanImageReport()}
/>
);
if (redirect) {
return <Redirect to={link} />;
}
const {
data = [],
total,
savedTablePageNumber = 0, // if page number is saved, pick it else start from 0
} = props;
const rowCounts = [
{
label: 10,
value: 10,
},
{
label: 25,
value: 25,
},
{
label: 50,
value: 50,
},
{
label: 100,
value: 100,
},
];
return (
<div>
<div style={{ display: 'flex' }}>
<div className="dataTables_length d-flex justify-content-start">
<label htmlFor="true">
{'Show '}
<select
style={{
backgroundColor: '#252525',
color: 'white',
borderRadius: '4px',
borderColor: '#252525',
}}
onChange={e => setRowCount(e)}
>
{rowCounts.map(el => (
<option key={el.value} value={el.value}>
{el.label}
</option>
))}
</select>
{' Entries'}
</label>
</div>
<NodesFilter resourceType="secret-scan" />
</div>
<DfTableV2
data={data}
columns={columns}
name="secrets-scan-table"
renderRowSubComponent={({ row }) => renderSubComponent({ row })}
showPagination
manual
defaultPageSize={rowCountValue}
page={savedTablePageNumber}
totalRows={total}
onPageChange={pageNumber => handlePageChange(pageNumber)}
/>
</div>
);
}