Reactjs 为什么我的React输入框没有呈现延迟响应,即使包装器类呈现输入框-React with Redux
问题陈述:调用了类render,但基础输入框不更新字段 描述:加载app类时,我进行fetch config调用以获取初始服务器配置。在异步调用之前,输入框将成功显示初始值。但是,加载异步数据后,该类调用render方法,但输入值不会更改 代码: InputBoxComponent 输入框减速机 贮藏 需要注意的几件事: 所有数据流点都表示更改,这意味着构造函数、操作、缩减器、mapStateToProps,然后是类呈现。不起作用的是inputBox值。异步调用后不会调用InputBox中的控制台日志。 我使用了受控表单,因为会有预填充的数据。 我尝试了使用纯组件的包装器,但由于getThunkNum不断被重复调用,它会进行无限循环 还建议,使用默认的预填充数据、初始配置加载数据以及正常的编辑流,有什么更好的策略 更新1 我在包装类的componentDidMount中尝试了FetchAPI,但仍然没有成功 更新2Reactjs 为什么我的React输入框没有呈现延迟响应,即使包装器类呈现输入框-React with Redux,reactjs,Reactjs,问题陈述:调用了类render,但基础输入框不更新字段 描述:加载app类时,我进行fetch config调用以获取初始服务器配置。在异步调用之前,输入框将成功显示初始值。但是,加载异步数据后,该类调用render方法,但输入值不会更改 代码: InputBoxComponent 输入框减速机 贮藏 需要注意的几件事: 所有数据流点都表示更改,这意味着构造函数、操作、缩减器、mapStateToProps,然后是类呈现。不起作用的是inputBox值。异步调用后不会调用InputBox中的控制
我从道具接收值,但我的输入值指向inputValue,这是状态对象的一个属性。那么我如何决定是打印道具还是状态属性呢?好的,我解决了问题 当您遇到显示默认值的问题时,预加载的服务器数据将预填充并使其可编辑。最好不要混合使用道具和useState。在每次更改时更改存储值的直接redux方法解决了这个问题 在上述问题中,inputBox如下所示: 从“React”导入React,{useState}
export const StatefulInputBox = (props) => {
const [inputValue, changeInputValue] = useState(props.value);
console.log(inputValue);
const onChange = (e) => {
const val = e.target.value;
changeInputValue(val);
if(props.onChange) {
props.onChange(val);
}
}
return (
<input value={inputValue} onChange={(e) => {
onChange(e)
}} />
)
};
请注意,为输入框赋值时会出现歧义。如果指定props.value,则用户无法键入。如果您分配value=inputValue,则服务器调用数据无法更改它
我删除了useState特性,并通过redux本身引导更改
export const DelayedResInputBox = (props) => {
return (
<input value={props.value} onChange={(e) => {
props.onChange(e.target.value)
}} />
)
};
在包装器类中,我使用redux将更新连接到存储
class DelayedResWrapperComponent extends Component {
constructor() {
super();
this.onChange = this.onChange.bind(this);
}
onChange(val) {
console.log(val);
this.props.saveUserResponse(val)
}
componentDidMount() {
this.props.getServerData();
}
render() {
return (
<DelayedResInputBox value={this.props.delayedRes.value} onChange={this.onChange}/>
)
}
}
const mapDelayedDispatchToProps = (dispatch) => {
return {
getServerData: () => {
dispatch(delayedResActions.getDelayedThunkRes())
},
saveUserResponse: (val) => {
dispatch(delayedResActions.setValueInStore(val))
}
}
};
通过这种方式,所有的小更改都通过存储进行路由,inputBox只获得一个更改命令。因此,我通过redux更新store实现了这一目标
注:门店变更并不意味着提交。所有较小的组件都将使用其值更新存储,然后“提交”按钮将仅触发服务器更新。这也有助于提取哑组件中不必要的逻辑
唯一的另一种方法是有三个输入框:一个禁用的输入框显示数据直到配置加载完成,一个可编辑的输入框显示useState
如果我错了,请随时纠正。如果您能创建一个sandbox@Jagrati你能帮我创建一个吗?我添加了一个强制更新ifprops.value!==inputValue{changeInputValueprops.value;}但这会阻止键入的更改:'我已经制作了一个代码沙盒:这似乎对我有用。请编辑它使其断裂。提示:您必须在构造函数中调用superprops。@xabitrigo您好,一开始您是正确的。应该是乔。但是在2秒之后,这个值应该是50,由action-getThunkNum返回。但我有问题。在一个新的回答中发布它没有歧义。React是基于组件的,只有当组件的道具或内部状态发生变化时才会重新加载。这个州是地方性的。但是,如果组件是无状态的,则更容易实现。Redux只是将整个应用程序视为一个大组件,全局状态通过props mapStateToProps传输到组件。它还为您提供了一种正式的方法来更改全局状态:分派映射到道具的操作,以便您可以使用它们,mapDispatchToProps是在还原器的中心位置处理的。需要明确的是:Redux使用道具与React交互,从不使用状态。这里没有含糊不清的地方。@xabitrigo您只是在谈论react-redux的连接函数,道具与react-redux使用的挂钩或redux本身无关。即使对于connect,这也只是故事的一半,因为connect返回的组件使用React上下文从全局存储读取。@Tarun如果您解决了问题,我很高兴,但这并不是对您问题的回答,您的解释是错误的,对任何未来的读者都没有帮助。请随意写一个实际的代码来解决你的问题。e、 g.当我停止将道具与useState混合以简化我的组件时,它解决了我的问题。我现在使用以下代码:@Tarun实现细节对这个问题不重要。您可以通过道具读取和操作全局Redux状态,也可以仅通过道具读取和操作全局Redux状态,您需要显式映射这些道具。你说有歧义,其实没有。使用所需的显式变量,没有歧义。
const initialState = {
value: 'Joe',
loading: false
}
export const nameReducer = (currentState = {...initialState}, action) => {
switch (action.type) {
case 'GET_INPUTBOX_NUM': {
const newState = {...currentState, ...action.payload};
return newState;
}
case 'SET_INPUTBOX_NUM': {
const newState = {...currentState, ...action.payload};
return newState;
}
case 'NAME_SUCCESS': {
let newState = {...currentState, ...action.payload};
return newState;
}
default: {
return currentState;
}
}
}
import {createStore, combineReducers, applyMiddleware} from 'redux';
import {buttonReducer} from "./components/Button/buttonReducers";
import {nameReducer} from "./reducers/inputBoxReducer";
import thunk from 'redux-thunk';
import {dropDownReducer} from "./reducers/dropDownReducer";
const rootReducer = combineReducers({
button: buttonReducer,
inputBox: nameReducer,
dropDown: dropDownReducer
});
export const store = createStore(rootReducer, applyMiddleware(thunk));
export const StatefulInputBox = (props) => {
const [inputValue, changeInputValue] = useState(props.value);
console.log(inputValue);
const onChange = (e) => {
const val = e.target.value;
changeInputValue(val);
if(props.onChange) {
props.onChange(val);
}
}
return (
<input value={inputValue} onChange={(e) => {
onChange(e)
}} />
)
};
export const DelayedResInputBox = (props) => {
return (
<input value={props.value} onChange={(e) => {
props.onChange(e.target.value)
}} />
)
};
class DelayedResWrapperComponent extends Component {
constructor() {
super();
this.onChange = this.onChange.bind(this);
}
onChange(val) {
console.log(val);
this.props.saveUserResponse(val)
}
componentDidMount() {
this.props.getServerData();
}
render() {
return (
<DelayedResInputBox value={this.props.delayedRes.value} onChange={this.onChange}/>
)
}
}
const mapDelayedDispatchToProps = (dispatch) => {
return {
getServerData: () => {
dispatch(delayedResActions.getDelayedThunkRes())
},
saveUserResponse: (val) => {
dispatch(delayedResActions.setValueInStore(val))
}
}
};