Если вам нужно сделать sed
на месте в сценарии bash
, и вы НЕ хотите, чтобы на месте было результат с .bkp-файлами, и у вас есть способ обнаружить os (скажем, используя ostype.sh ), - тогда следующий хак с встроенной bash
оболочкой eval
должен работать:
OSTYPE="$(bash ostype.sh)"
cat > myfile.txt <<"EOF"
1111
2222
EOF
if [ "$OSTYPE" == "osx" ]; then
ISED='-i ""'
else # $OSTYPE == linux64
ISED='-i""'
fi
eval sed $ISED 's/2222/bbbb/g' myfile.txt
ls
# GNU and OSX: still only myfile.txt there
cat myfile.txt
# GNU and OSX: both print:
# 1111
# bbbb
# NOTE:
# if you just use `sed $ISED 's/2222/bbbb/g' myfile.txt` without `eval`,
# then you will get a backup file with quotations in the file name,
# - that is, `myfile.txt""`
Здесь простой ответ: вам, вероятно, не следует использовать useCallback
здесь. Смысл useCallback
состоит в том, чтобы передать один и тот же экземпляр функции оптимизированным компонентам (например, PureComponent
или React.memo
компонентам), чтобы избежать ненужных повторных отображений.
В этом случае вы не имеете дело с оптимизированными компонентами (или, как я подозреваю, в большинстве случаев), поэтому на самом деле нет причин запоминать обратные вызовы, как с useCallback
.
Предположим, что запоминание важно, однако, лучшее решение здесь, вероятно, состоит в том, чтобы использовать одну функцию вместо пяти: вместо уникальной функции для каждой кнопки выполняется закрытие key
, вы можете прикрепить [ 1112] к элементу:
<button data-key={key}>{key}</button>
А затем прочитайте ключ из event.target.dataset["key"]
внутри обработчика одного клика:
const Example = (props) => {
// Single callback, shared by all buttons
const onClick = React.useCallback((e) => {
// Check which button was clicked
const key = e.target.dataset["key"]
console.log("You clicked: ", key);
}, [/* dependencies */]);
return(
<div>
{
_.times(5, (key) => {
return (
<button data-key={key} onClick={onClick}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
[ 1129] При всем этом можно запоминать несколько функций в одном хуке. useCallback(fn, deps)
эквивалентно useMemo(() => fn, deps)
, а useMemo
может использоваться для запоминания нескольких функций одновременно:
const clickHandlers = useMemo(() => _.times(5, key =>
() => console.log("You clicked", key)
), [/* dependencies */]);
const Example = (props) => {
const clickHandlers = React.useMemo(() => _.times(5, key =>
() => console.log("You clicked", key)
), [/* dependencies */])
return(
<div>
{
_.times(5, (key) => {
return (
<button onClick={clickHandlers[key]}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
Возможно, есть случай, когда это полезно, но в этом случае я бы либо оставил его в покое (и не беспокоился об оптимизации), либо использовал бы один обработчик для каждой кнопки.