input
. input.onChange
редукса. formSelector
reduxForm с connect
[116] для доступа к formProps внутри компонента в this.props
(приведенный ниже рабочий пример уже включает эту функциональность) components / CustomInput.js
import React from "react";
const CustomInput = ({
// we'll intercept redux's "onChange" func, while leaving the other
// input props as is in "inputProps"
input: { onChange, ...inputProps },
// the "handleChange" func below is the parent func that will handle input changes
handleChange,
// "rest" contains any additional properties (className, placeholder, type ...etc)
...rest
}) => (
// we spread out the "inputProps" and the "rest" of the props, then we add
// an "onChange" event handler that returns the "event" and the
// input's "onChange" func to our "handleChange" parent func
handleChange(e, onChange)} />
);
export default CustomInput;
контейнеров / Form.js
class ControlledFormValue extends PureComponent {
// this parent func will handle updates through the "event.target.value";
// the value can be changed/altered and then passed to the input's
// "onChange" func to update the field
handleChange = ({ target: { value } }, onChange) => {
// this will alter the value by adding a "-" after each input update
onChange(`${value}-`);
setTimeout(() => console.log(this.props.values), 500);
};
render() {
return (
);
}
}
Рабочий пример : https://codesandbox.io/s/lx1r4yjwy7
Я перенес бы реализацию LongRunningOperationToFetchFactor с чем-то вроде этого. Я использую ограниченные по объему блокировки Повышения, но Вы можете так что-то похожее с другими платформами блокировки.
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <map>
using namespace std;
static boost::mutex myMutex;
static map<int,double> results;
double CachedLongRunningOperationToFetchFactor( int key )
{
{
boost::mutex::scoped_lock lock(myMutex);
map<int,double>::iterator iter = results.find(key);
if ( iter != results.end() )
{
return (*iter).second;
}
}
// not in the Cache calculate it
result = LongRunningOperationToFetchFactor( key );
{
// we need to lock the map again
boost::mutex::scoped_lock lock(myMutex);
// it could be that another thread already calculated the result but
// map assignment does not care.
results[key] = result;
}
return result;
}
Если это действительно - длительная операция затем, стоимость блокировки Взаимного исключения должна быть минимальной.
Было не совсем ясно от Вас вопрос, но если функциональный LongRunningOperationToFetchFactor является функцией членства Вас класс затем, Вы хотите карту быть изменяемой картой в том же самом классе. Я единственное статическое взаимное исключение для доступа все еще достаточно быстр все же.
Если я не понимаю, для меня кажется очевидным, что Вы хотите сделать это помехами:
double AdjustData(double d) const {
static const double kAdjustFactor = LongRunningOperationToFetchFactor();
return kAdjustFactor * d;
}
Тем путем Вы только выбираете фактор однажды.
Я не сделал бы этот кэш локальными помехами. Изменяемая карта является решением для кэширования результатов. Иначе это сделает Вашу функцию бесполезной, поскольку различные объекты Вашего класса совместно используют тот же кэш, как локальный статический кэш является тем же для всех объектов. Можно использовать локальные помехи, если результат не зависит от объекта все же. Но затем я спросил бы меня, почему функция является нестатическим членом Вашего объекта, если это не должно получать доступ ни к какому состоянию его.
Поскольку Вы говорите, что это должно быть ориентировано на многопотоковое исполнение - если различные потоки могут назвать функцию членства на том же объекте, Вы, вероятно, хотите использовать взаимное исключение. boost::thread
хорошая библиотека должна использовать.
Можно использовать шаблон "одиночка" (1) для с классом, который выполняет продолжительную операцию и кэширует результат. Этот экземпляр мог затем использоваться в функциях членства константы других классов. Полагайте, что взаимное исключение для защиты вставляет и извлечения от структуры данных карты для потокобезопасности. Если многопоточная производительность является огромной проблемой, то можно отметить ключи как происходящие, чтобы препятствовать тому, чтобы несколько потоков вычислили тот же ключ одновременно.
#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;
class FactorMaker {
map<int, double> cache;
double longRunningFetch(int key)
{
const double factor = static_cast<double> (rand()) / RAND_MAX;
cout << "calculating factor for key " << key << endl;
// lock
cache.insert(make_pair(key, factor));
// unlock
return factor;
}
public:
double getFactor(int key) {
// lock
map<int, double>::iterator it = cache.find(key);
// unlock
return (cache.end() == it) ? longRunningFetch(key) : it->second;
}
};
FactorMaker & getFactorMaker()
{
static FactorMaker instance;
return instance;
}
class UsesFactors {
public:
UsesFactors() {}
void printFactor(int key) const
{
cout << getFactorMaker().getFactor(key) << endl;
}
};
int main(int argc, char *argv[])
{
const UsesFactors obj;
for (int i = 0; i < 10; ++i)
obj.printFactor(i);
for (int i = 0; i < 10; ++i)
obj.printFactor(i);
return EXIT_SUCCESS;
}
(1) Шаблон "одиночка" может быть чрезвычайно пропущен. Так, воздержитесь от схождения с ума с ним, если Вы видите его впервые.