Rau*_*hez 7 javascript firebase reactjs google-cloud-firestore
我不知道为什么我的React组件渲染两次.所以我从params中提取一个电话号码并将其保存到状态,以便我可以搜索Firestore.一切似乎工作得很好,除了它呈现两次......第一个呈现电话号码和零点.第二次渲染所有数据都正确显示.有人可以指导我解决方案.
class Update extends Component {
constructor(props) {
super(props);
const { match } = this.props;
this.state = {
phoneNumber: match.params.phoneNumber,
points: 0,
error: ''
}
}
getPoints = () => {
firebase.auth().onAuthStateChanged((user) => {
if(user) {
const docRef = database.collection('users').doc(user.uid).collection('customers').doc(this.state.phoneNumber);
docRef.get().then((doc) => {
if (doc.exists) {
const points = doc.data().points;
this.setState(() => ({ points }));
console.log(points);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
const error = 'This phone number is not registered yet...'
this.setState(() => ({ error }));
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
} else {
history.push('/')
}
});
}
componentDidMount() {
if(this.state.phoneNumber) {
this.getPoints();
} else {
return null;
}
}
render() {
return (
<div>
<div>
<p>{this.state.phoneNumber} has {this.state.points} points...</p>
<p>Would you like to redeem or add points?</p>
</div>
<div>
<button>Redeem Points</button>
<button>Add Points</button>
</div>
</div>
);
}
}
export default Update;
Run Code Online (Sandbox Code Playgroud)
fru*_*oaf 62
这是因为 React 严格模式代码。
从 ReactDOM.render 代码中删除 -> React.StrictMode。
每次重新渲染时都会渲染 2 次:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)
将渲染 1 次:
ReactDOM.render(
<>
<App />
</>,
document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)
Aks*_*ain 15
React.StrictMode,使其渲染两次,这样我们就不会在以下位置放置副作用
constructor
componentWillMount (or UNSAFE_componentWillMount)
componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
componentWillUpdate (or UNSAFE_componentWillUpdate)
getDerivedStateFromProps
shouldComponentUpdate
render
setState updater functions (the first argument)
Run Code Online (Sandbox Code Playgroud)
所有这些方法都会被多次调用,因此避免其中产生副作用非常重要。如果我们忽略这一原则,很可能会导致不一致的状态问题和内存泄漏。
React.StrictMode 无法立即发现副作用,但它可以通过有意调用两次某些关键函数来帮助我们找到副作用。
这些功能是:
Class component constructor, render, and shouldComponentUpdate methods
Class component static getDerivedStateFromProps method
Function component bodies
State updater functions (the first argument to setState)
Functions passed to useState, useMemo, or useReducer
Run Code Online (Sandbox Code Playgroud)
这种行为肯定会对性能产生一些影响,但我们不应该担心,因为它只发生在开发中而不是生产中。
信用:https://mariosfakiolas.com/blog/my-react-components-render-twice-and-drive-me-crazy/
Sha*_*ari 14
您正在以严格模式运行您的应用程序。转到 index.js 并注释严格模式标签。你会发现一个渲染。
发生这种情况是 React.StrictMode 的一个有意特性。它只发生在开发模式中,应该有助于在渲染阶段发现意外的副作用。
从文档:
严格模式无法自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。这是通过有意重复调用以下函数来完成的:...
^ 在本例中为render函数。
使用 React.StrictMode 时可能导致重新渲染的官方文档:
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
React在getPoints完成异步操作之前渲染组件.
因此,第一个render显示的初始状态points是0,那么componentDidMount被称为并触发异步操作.
完成异步操作并更新状态后render,将使用新数据触发另一个操作.
如果需要,您可以显示正在获取数据的加载程序或指示符,但尚未准备好使用条件呈现进行显示.
只需添加另一个布尔键,例如isFetching,在调用服务器时将其设置为true,并在收到数据时将其设置为false.
您的渲染可能如下所示:
render() {
const {isFetching} = this.state;
return (
<div>
{
isFetching ? <div>Loading...</div> : (
<div>
<p>{this.state.phoneNumber} has {this.state.points} points...</p>
<p>Would you like to redeem or add points?</p>
</div>
<div>
<button>Redeem Points</button>
<button>Add Points</button>
</div>
</div>
)
}
);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这是通过反应故意完成的,以避免这种删除
<React.StrictMode> </React.StrictMode>
Run Code Online (Sandbox Code Playgroud)
来自index.js
| 归档时间: |
|
| 查看次数: |
11378 次 |
| 最近记录: |