Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 组件在单击导航链接后重新渲染&多次加载相同的数据_Reactjs_Redux_React Redux_Fetch_React Router Dom - Fatal编程技术网

Reactjs 组件在单击导航链接后重新渲染&多次加载相同的数据

Reactjs 组件在单击导航链接后重新渲染&多次加载相同的数据,reactjs,redux,react-redux,fetch,react-router-dom,Reactjs,Redux,React Redux,Fetch,React Router Dom,我制作了一个示例电子商务站点用于实践&我使用了React、Redux和Router-DOM。这是第一次,所有东西都能完美地装载。它有两条路线。主页路径将我带到出现问题的主页&上传路径将我带到上传页面。但是,当我再次返回HomeRoute时,从API获取的数据不会重新呈现,相反,状态会加倍,我的意思是,现有状态保持不变,但由于某些原因,数据会再次获取,元素会呈现2次 身体元素,如果我从另一条路线返回到它会加倍。。。 动作创造者 请帮助我我已经搜索了4个小时的解决方案…如果您能帮助我,那就太好了…提

我制作了一个示例电子商务站点用于实践&我使用了React、Redux和Router-DOM。这是第一次,所有东西都能完美地装载。它有两条路线。主页路径将我带到出现问题的主页&上传路径将我带到上传页面。但是,当我再次返回HomeRoute时,从API获取的数据不会重新呈现,相反,状态会加倍,我的意思是,现有状态保持不变,但由于某些原因,数据会再次获取,元素会呈现2次

身体元素,如果我从另一条路线返回到它会加倍。。。 动作创造者 请帮助我我已经搜索了4个小时的解决方案…如果您能帮助我,那就太好了…提前感谢您使用useEffect挂钩时,第二个参数是依赖项。。因此,如果依赖项发生变化,它会再次调用该函数。现在,由于GetProducts是一个函数,它将永远不会被调用。相反,你应该把产品放在那里


很难看出代码中发生了什么。但我怀疑也许这就是问题所在。否则请告诉我。

对于函数,我可以使用useCallback包装它并将其传递给use effect作为第二个参数吗?与你的练习相比有什么不同吗?多谢各位much@baileyhaldwin,这使情况比以前更糟。在它被渲染两次之前,当我从其他路线返回到这条路线。现在,它总是被重新渲染…有没有其他方法来修复这个问题?谢谢你的回答…很抱歉上传了太多的代码。。。
const Body = ({getProducts, deleteProduct, productState})=>{
    const {products, loading, error} = productState;

    useEffect(()=>{
        getProducts()
    }, [getProducts])

    const deleteProducts = (id)=>{
        deleteProduct(id)
    }

    return (
        <div className="display-flex width-full flex-wrap justify-content-center">
            {!loading && !error && products?products.map(product=>(
                product.data?product.data.map(d=>(
                    <BodyDiv
                        key={uuid.v4()}
                        imgSrc={d.imgSrc}
                        title={d.title}
                        details={d.details}
                        description={d.description}
                        onClick={()=>deleteProducts(d._id)}
                    />    
                )):product.map(d=>(
                    <BodyDiv
                    key={uuid.v4()}
                    imgSrc={d.imgSrc}
                    title={d.title}
                    details={d.details}
                    description={d.description}
                    onClick={()=>deleteProducts(d._id)}
                /> 
                ))
            ))
            : loading&&!error
            ? <div className="vertical-center-strict horizontal-center-strict">Loading.......</div>
            : <div className="vertical-center-strict horizontal-center-strict">No Internet!</div>
        }
        </div>
    )
}

const BodyDiv = (props)=>{
    return(
        <div className="container-div width-full card tiny-padding align-self-start">
        <img title={props.title} className="img-responsive hover-filter" src={props.imgSrc}/>
        <h2 className="text-align-center">{props.title}</h2>
        <h5>{props.details}</h5>
        <p className="text-align-justify">{props.description}</p>
        <button 
        className="btn btn-danger"
        onClick={props.onClick}
        >Delete</button>
        </div>
    )   
} 


BodyDiv.propTypes = {
    title: PropTypes.string.isRequired,
    img: PropTypes.string,
    details: PropTypes.string.isRequired,
    description: PropTypes.string,
    onClick: PropTypes.func

}
const mapStateToProps = (state)=>({
    productState: state.productState
})
const conn = connect(mapStateToProps, {getProducts, deleteProduct})(Body)

export default conn;
//Store
import {createStore, applyMiddleware} from "redux"
import rootReducer from "./reducers/index"
import thunk from "redux-thunk"


const middleWare = [thunk]

const store = createStore(rootReducer, applyMiddleware(...middleWare))

export default store


//RootReducer
import {
  FETCHED_PRODUCTS,
  FETCHING_PRODUCTS,
  ERROR_GET_PRODUCTS,
  DELETED_PRODUCT,
  ERROR_DELETING_PRODUCT
} from "../actions/productActions";

const initialState = {
  products: [],
  loading: true,
  error: false,
};

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCHING_PRODUCTS:
      return {
        ...state,
        loading: true,
      };
    case FETCHED_PRODUCTS:
      return {
        ...state,
        products: state.products.concat(action.payload),
        loading: false,
        error: false,
      };
    case ERROR_GET_PRODUCTS:
      return {
        ...state,
        loading: false,
      };
    case DELETED_PRODUCT:
      return {
        ...state,
        products: state.products.map((product) =>
          product.data.filter((d) => d._id !== action.payload)
        ),
        error: false,
      };
    case ERROR_DELETING_PRODUCT:
      return {
        ...state,
        error: true,
      };
    default:
      return state;
  }
};

export default productReducer;
export const getProducts = (payload)=>(dispatch)=>{
    return(
     fetch("/api/products")
    .then(res=>{
        dispatch({
            type:FETCHING_PRODUCTS
        })
        if(!res.ok){
            dispatch({
                type: ERROR_GET_PRODUCTS
            })
        }
    return res.json();
    })
    .then(json=>{
        if(json)dispatch({
        type: FETCHED_PRODUCTS,
        payload: json
    })
})
    .catch(err=>{
        console.log("Error!! failed to fetch data: "+ err)
    })
    )
} 




export const deleteProduct = (payload)=>dispatch=>{
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

var requestOptions = {
  method: 'DELETE',
  headers: myHeaders,
  body: JSON.stringify({"_id": payload}),
  redirect: 'follow'
};
    fetch("/api/product-delete", requestOptions).then(res=>{
        dispatch({
            type: DELETED_PRODUCT,
            payload
        })
        if(res.status === 501 || res.status === 403){
             dispatch({
                 type: ERROR_DELETING_PRODUCT,
             })
         }
    })
    .catch(err=>{
        console.log("Failed to Delete")
    })
}

useEffect(()=>{
        getProducts()
    }, [products])
//will refetch data everytime product state is updated.