Kat*_*nko 104 javascript ecmascript-6 reactjs
我正在编写一个脚本,根据下拉的高度和屏幕上输入的位置,将输入下移或高于输入.另外,我想根据其方向将修改器设置为下拉列表.但是setState
在内部使用componentDidUpdate
会创建一个无限循环(很明显)
我已经找到了getDOMNode
直接使用和设置classname到dropdown 的解决方案,但我觉得使用React工具应该有更好的解决方案.有谁能够帮我?
这是工作代码的一部分getDOMNode
(有点忽略定位逻辑以简化代码)
let SearchDropdown = React.createClass({
componentDidUpdate(params) {
let el = this.getDOMNode();
el.classList.remove('dropDown-top');
if(needToMoveOnTop(el)) {
el.top = newTopValue;
el.right = newRightValue;
el.classList.add('dropDown-top');
}
},
render() {
let dataFeed = this.props.dataFeed;
return (
<DropDown >
{dataFeed.map((data, i) => {
return (<DropDownRow key={response.symbol} data={data}/>);
})}
</DropDown>
);
}
});
Run Code Online (Sandbox Code Playgroud)
这里是setstate的代码(创建一个无限循环)
let SearchDropdown = React.createClass({
getInitialState() {
return {
top: false
};
},
componentDidUpdate(params) {
let el = this.getDOMNode();
if (this.state.top) {
this.setState({top: false});
}
if(needToMoveOnTop(el)) {
el.top = newTopValue;
el.right = newRightValue;
if (!this.state.top) {
this.setState({top: true});
}
}
},
render() {
let dataFeed = this.props.dataFeed;
let class = cx({'dropDown-top' : this.state.top});
return (
<DropDown className={class} >
{dataFeed.map((data, i) => {
return (<DropDownRow key={response.symbol} data={data}/>);
})}
</DropDown>
);
}
});
Run Code Online (Sandbox Code Playgroud)
dam*_*nmr 97
你可以setState
在里面使用componentDidUpdate
.问题是,你创建一个无限循环,因为没有中断条件.
基于以下事实:一旦呈现组件,您需要浏览器提供的值,我认为您使用的方法componentDidUpdate
是正确的,它只需要更好地处理触发的条件setState
.
mic*_*oon 54
如果你setState
在里面使用componentDidUpdate
它更新组件,导致一个调用componentDidUpdate
,随后setState
再次调用导致无限循环.您应该有条件地呼叫setState
并确保最终发生违反呼叫的情况,例如:
componentDidUpdate: function() {
if (condition) {
this.setState({..})
} else {
//do something else
}
}
Run Code Online (Sandbox Code Playgroud)
如果你只是通过向它发送道具来更新组件(它没有被setState更新,除了componentDidUpdate中的情况),你可以调用setState
inside componentWillReceiveProps
而不是componentDidUpdate
.
Abd*_*UMI 54
该componentDidUpdate
签名void::componentDidUpdate(previousProps, previousState)
.有了这个,您将能够测试哪些道具/状态是脏的,并相应地调用setState
.
componentDidUpdate(previousProps, previousState) {
if (previousProps.data !== this.props.data) {
this.setState({/*....*/})
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子将帮助你理解React Life Cycle Hooks。
您可以setState
在getDerivedStateFromProps
方法 ie 中static
并在道具更改后触发方法componentDidUpdate
。
在componentDidUpdate
您将获得3 PARAM从返回getSnapshotBeforeUpdate
。
您可以检查此代码和框链接
// Child component
class Child extends React.Component {
// First thing called when component loaded
constructor(props) {
console.log("constructor");
super(props);
this.state = {
value: this.props.value,
color: "green"
};
}
// static method
// dont have access of 'this'
// return object will update the state
static getDerivedStateFromProps(props, state) {
console.log("getDerivedStateFromProps");
return {
value: props.value,
color: props.value % 2 === 0 ? "green" : "red"
};
}
// skip render if return false
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
// return nextState.color !== this.state.color;
return true;
}
// In between before real DOM updates (pre-commit)
// has access of 'this'
// return object will be captured in componentDidUpdate
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
return { oldValue: prevState.value };
}
// Calls after component updated
// has access of previous state and props with snapshot
// Can call methods here
// setState inside this will cause infinite loop
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate: ", prevProps, prevState, snapshot);
}
static getDerivedStateFromError(error) {
console.log("getDerivedStateFromError");
return { hasError: true };
}
componentDidCatch(error, info) {
console.log("componentDidCatch: ", error, info);
}
// After component mount
// Good place to start AJAX call and initial state
componentDidMount() {
console.log("componentDidMount");
this.makeAjaxCall();
}
makeAjaxCall() {
console.log("makeAjaxCall");
}
onClick() {
console.log("state: ", this.state);
}
render() {
return (
<div style={{ border: "1px solid red", padding: "0px 10px 10px 10px" }}>
<p style={{ color: this.state.color }}>Color: {this.state.color}</p>
<button onClick={() => this.onClick()}>{this.props.value}</button>
</div>
);
}
}
// Parent component
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { value: 1 };
this.tick = () => {
this.setState({
date: new Date(),
value: this.state.value + 1
});
};
}
componentDidMount() {
setTimeout(this.tick, 2000);
}
render() {
return (
<div style={{ border: "1px solid blue", padding: "0px 10px 10px 10px" }}>
<p>Parent</p>
<Child value={this.state.value} />
</div>
);
}
}
function App() {
return (
<React.Fragment>
<Parent />
</React.Fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
110030 次 |
最近记录: |