import React from "react";
import { render } from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider, connect } from "react-redux";
import thunk from "redux-thunk";
const disabled = (state = true, action) => {
return action.type === "TOGGLE" ? !state : state;
};
class Button extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.disabled !== this.props.disabled && !this.props.disabled) {
// this.ref.focus(); // uncomment this to see the desired effect
}
}
render() {
const { props } = this;
console.log("rendering", props.value);
return (
<div>
<input
type="checkbox"
onClick={() => {
props.toggle();
this.ref.focus(); // doesn't work
}}
/>
<input
disabled={props.disabled}
ref={ref => {
this.ref = ref;
}}
/>
</div>
);
}
}
const toggle = () => ({
type: "TOGGLE"
});
const A = connect(state => ({ disabled: state }), { toggle })(Button);
const App = () => (
<Provider store={createStore(disabled, applyMiddleware(thunk))}>
<A />
</Provider>
);
render(<App />, document.getElementById("root"));
我想在选中复选框时聚焦 input
。
但是,this.ref.focus()
必须仅在组件使用 props.disabled === false
重新呈现后调用,作为 输入
with disabled
prop 无法聚焦。
如果我执行 componentDidUpdate
中的逻辑,我就能实现我想要的。但这不是一个干净的解决方案,因为逻辑特定于 onClick
处理程序而不是生命周期事件。
还有其他方法可以实现吗? (最好有一个有效的codesandbox示例)
最佳答案
我认为最好的办法是不依赖 refs 使用状态来管理焦点。
此解决方案改为在输入上使用 autoFocus
属性,并在复选框状态更改时修改它。
import React from "react";
import { render } from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider, connect } from "react-redux";
import thunk from "redux-thunk";
const disabled = (state = true, action) => {
return action.type === "TOGGLE" ? !state : state;
};
class Button extends React.Component {
state = {
checked: false,
focus: false
};
componentDidUpdate(prevProps, prevState) {
if (prevState.checked !== this.state.checked) {
this.props.toggle();
this.setState({
focus: this.state.checked
});
}
}
render() {
const { props } = this;
const { checked, focus } = this.state;
console.log("rendering", props.value, checked);
return (
<div>
<input
type="checkbox"
checked={checked}
onClick={({ target }) => {
this.setState({ checked: target.checked });
}}
/>
<input key={`input_${checked}`} autoFocus={focus} />
</div>
);
}
}
const toggle = () => ({
type: "TOGGLE"
});
const A = connect(state => ({ disabled: state }), { toggle })(Button);
const App = () => (
<Provider store={createStore(disabled, applyMiddleware(thunk))}>
<A />
</Provider>
);
render(<App />, document.getElementById("root"));
我不确定为什么,但是在组件先前被禁用时更改 autoFocus
属性不会触发重新呈现输入。所以我还在输入中添加了一个键来强制它。
关于javascript - Redux-thunk 派发一个 Action 并等待重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49892010/