Javascript React/Redux:将jQuery事件处理程序放在组件中等待异步数据的位置
当我阅读ReactJS文档时,我知道放置redux操作调用的最佳生命周期方法是Javascript React/Redux:将jQuery事件处理程序放在组件中等待异步数据的位置,javascript,jquery,reactjs,redux,Javascript,Jquery,Reactjs,Redux,当我阅读ReactJS文档时,我知道放置redux操作调用的最佳生命周期方法是componentDidMount,但我发现在该生命周期方法中很难执行任何jquery工作: class App extends React.Component { constructor(props) { super(props); this.state = { isAsyncLoaded: false } } stati
componentDidMount
,但我发现在该生命周期方法中很难执行任何jquery工作:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isAsyncLoaded: false
}
}
static getDerivedStateFromProps(nextProps, prevState) {
let {getData} = nextProps.someData;
let {hasSuccess, isLoading} = getData;
if (!isLoading && hasSuccess) {
return {
isAsyncLoaded: true
}
} else {
return {
isAsyncLoaded: false
}
}
return null;
}
componentDidMount() {
this.props.getSomeData();
$('p').css('color', 'red');
}
render() {
if (!this.state.isAsyncLoaded) return null;
return (
<p>{this.props.someData.data}</p>
)
}
}
function mapStateToProps(state) {
return {
someData: state.someData
}
}
export default connect(mapStateToProps, {getSomeData})(App);
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
isAsyncLoaded:错误
}
}
静态getDerivedStateFromProps(下一步,上一步){
让{getData}=nextrops.someData;
设{hassucces,isLoading}=getData;
如果(!isLoading&&Hassucces){
返回{
isAsyncLoaded:正确
}
}否则{
返回{
isAsyncLoaded:错误
}
}
返回null;
}
componentDidMount(){
this.props.getSomeData();
$('p').css('color','red');
}
render(){
如果(!this.state.isAsyncLoaded)返回null;
返回(
{this.props.someData.data}
)
}
}
函数MapStateTops(状态){
返回{
someData:state.someData
}
}
导出默认连接(MapStateTops,{getSomeData})(应用程序);
这里是jquery$('p').css('color','red')代码>部分找不到
元素,因为isAsyncLoaded
不为true,并且render
函数返回null
我的问题是,在不向我的应用程序引入容器视图(父子)组件关系的情况下,如何解决这个问题?在我开始之前,请注意几点:使用jQuery之类的事件处理程序通常是React中的反模式。它可能会对DOM造成意外的副作用,理想情况下应该完全通过react中的受控组件来处理
如果您需要使用jQuery(对于快速/脏的插件或类似的东西),我建议使用单独的组件。当该组件挂载时,它会触发一个事件,您可以钩住该事件并触发jQuery代码:
class MyJqueryComponent extends React.Component {
constructor(props) {
super(props);
this.mountPoint = React.createRef();
}
componentDidMount() {
// Do your jQuery stuff here
$(this.mountPoint).find(...);
}
render() {
return (
<p ref={this.mountPoint}>{this.props.data}</p>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isAsyncLoaded: false
}
}
static getDerivedStateFromProps(nextProps, prevState) {
let {getData} = nextProps.someData;
let {hasSuccess, isLoading} = getData;
if (!isLoading && hasSuccess) {
return {
isAsyncLoaded: true
}
} else {
return {
isAsyncLoaded: false
}
}
return null;
}
componentDidMount() {
this.props.getSomeData();
$('p').css('color', 'red');
}
render() {
if (!this.state.isAsyncLoaded) return null;
return (
<p><MyJqueryComponent data={this.props.someData.data} /></p>
)
}
}
function mapStateToProps(state) {
return {
someData: state.someData
}
}
export default connect(mapStateToProps, {getSomeData})(App);
类MyJqueryComponent扩展了React.Component{
建造师(道具){
超级(道具);
this.mountPoint=React.createRef();
}
componentDidMount(){
//在这里执行jQuery操作
$(this.mountPoint).find(…);
}
render(){
返回(
{this.props.data}
);
}
}
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
isAsyncLoaded:错误
}
}
静态getDerivedStateFromProps(下一步,上一步){
让{getData}=nextrops.someData;
设{hassucces,isLoading}=getData;
如果(!isLoading&&Hassucces){
返回{
isAsyncLoaded:正确
}
}否则{
返回{
isAsyncLoaded:错误
}
}
返回null;
}
componentDidMount(){
this.props.getSomeData();
$('p').css('color','red');
}
render(){
如果(!this.state.isAsyncLoaded)返回null;
返回(
)
}
}
函数MapStateTops(状态){
返回{
someData:state.someData
}
}
导出默认连接(MapStateTops,{getSomeData})(应用程序);
在componentDidUpdate()中应用jquery代码
componentDidUpdate(prevProps,prevState){
//仅在首次呈现异步代码时执行代码
if(prevState.isAsyncLoaded==false&&this.state.isAsyncLoaded==true){
//在这里执行jQuery操作
$(this.mountPoint).find(…);
}
}
现场演示:为什么一开始就要使用jQuery?jQuery不应该在react方式中占有一席之地。我理解你的意思,但是假设我有一个重要的插件,它依赖于jquery。我看不出这与创建容器-视图层次结构和只对子组件使用jquery有什么不同。它看起来更脏,而且设计过度。@BarışÜrüm欢迎来解释为什么这是一种反模式:虽然这是一个可行的替代方案,但我通常反对这些设计决策,因为这会使调试变得更加困难。当另一个程序员添加另一个fetch语句来更新数据时会发生什么isAsyncLoaded
已经为true,因此它不会翻转,并且jQuery代码永远不会执行。新的事件处理程序无法绑定。添加此内容的理想位置应该是在呈现此异步组件时。@FrankerZ我们需要从使用jQuery和react是一种反模式这一点开始。这个解决方案只是一个逃生舱。我仍然坚持,如果我有一个我想要使用的强制jquery插件,我就必须进行这种集成。@Barışrüm这是一种务实的方法。使用jQ,直到找到/创建给定插件的替代品,因为原生react实现将更容易维护。