我正在开发一个宠物店反应 Dapp,在某些时候要求是自动刷新宠物收养者列表..所以为此我尝试使用 useEffect 和 useSelector 从商店获取数据......但问题是它正在运行,我可以在控制台中看到它,但它不会刷新列表。要获得更新的列表,我需要刷新页面,这不是一个好主意。
问题
我打开了两个相同的 UI 选项卡,在 UI 上,我收养了一只宠物,它会更新收养者列表并隐藏收养宠物的按钮,但同时第二个 UI 不会自动更新,如果我需要查看任何更新我必须刷新 UI(页面)才能获得更新。
我希望它只刷新列表而不刷新整个页面,只更新页面的特定部分不需要刷新整个页面...
adoptionSlice.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import Web3 from "web3";
import Adoption from '../contracts/Adoption'
export const initWeb3 = createAsyncThunk(
'InitWeb3',
async (a, thunkAPI) => {
console.log('initWeb3 a: ', a)
console.log('initWeb3 thunkapi: ', thunkAPI)
console.log('initWeb3 dispatch: ', thunkAPI.dispatch)
try {
if (Web3.givenProvider) {
const web3 = new Web3(Web3.givenProvider)
await Web3.givenProvider.enable();
web3.eth.handleRevert = true;
const networkId = await web3.eth.net.getId();
const network = Adoption.networks[networkId];
const contract = new web3.eth.Contract(Adoption.abi, network.address)
const addresses = await web3.eth.getAccounts()
thunkAPI.dispatch(loadAdopters({
contract: contract,
address: addresses[0]
}))
console.log(addresses)
return {
web3: web3,
contract: contract,
address: addresses[0],
}
}
else {
console.log('Error In Loading Web3')
}
}
catch (err) {
console.log('Error In Loading')
}
}
)
// export const loadAdopters = createAsyncThunk(
// 'LoadAdopters',
// async (a, thunkAPI) => {
// console.log('in loadAdopters a = ', a);
// console.log('in loadAdopters thunkApi = ', thunkAPI);
// console.log('in loadAdopters thunkApi state = ', thunkAPI.getState());
// const contract = thunkAPI.getState().adoptReducer.contract;
// console.log('loadadopters contract = ', contract);
// const adopterList = await contract.methods.getAdopters().call()
// return adopterList
// }
// )
export const loadAdopters = createAsyncThunk(
"LoadAdopters",
async(data,thunkAPI)=>{
const adopterList = await data.contract.methods.getAdopters().call();
return adopterList;
}
)
const adoptSlice = createSlice({
name: 'AdoptSlice',
initialState: {
web3: null,
contract: null,
address: null,
adopters: [],
adoptInProgress: false,
adopError: false,
adoptErrorMessage: '',
releasingPetStatus: false,
releasePetError: '',
releaseErrorMessage: ''
},
reducers: {
adopt: () => { }
},
extraReducers: {
[initWeb3.fulfilled]: (state, action) => {
console.log("In fullfil = ", state);
console.log("In fullfil = ", action);
state.web3 = action.payload.web3;
state.contract = action.payload.contract;
state.address = action.payload.address;
},
[loadAdopters.fulfilled]: (state, action) => {
state.adopters = action.payload
},
}
export const adopReducer = adoptSlice.reducer;
export const { adopt } = adoptSlice.actions;
<块引用>
adoptionSlice.js 用于加载 web3 并获取 loadAdopters
App.js
function App() {
const dispatch = useDispatch();
const web3 = useSelector((state)=>{
console.log("state in app= ",state);
return state.adoptReducer.web3
})
useEffect(()=>{
dispatch(initWeb3());
// eslint-disable-next-line react-hooks/exhaustive-deps
},[])
return (
<div>
<PetList></PetList>
</div>
);
}
export default App;
Adopter.js
import React from 'react'
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { loadAdopters } from '../store/adoptSlice'
export const Adopters = () => {
const dispatch = useDispatch()
const adoptersList = useSelector((state) => {
return state.adoptReducer.adopters
})
useEffect(() => {
const interval = setInterval(() => {
dispatch(loadAdopters())
console.log('updated')
}, 2000)
return () => clearInterval(interval)
}, [])
return (
<div>
<div>Adopters List</div>
<div>
{
adoptersList.map((list, index) => (
list !== '0x0000000000000000000000000000000000000000' ? <div key={index}>index {index} : {list}</div> : null
))
}
</div>
</div>
)
}
<块引用>
Adopter.js 从商店获取采用者列表
答案 0 :(得分:0)
我想根据您所解释的内容,您尝试实现的目标是不可能的。主要有两个问题。
当您在两个不同的选项卡上打开同一个 React 应用程序时,它的本质是两个不同的应用程序实例,它们没有任何共同点。每个都有自己的状态、redux 等。
从您的问题中可以理解的是,您希望每当执行更改/更新您在某些数据库中的值的操作时,您都希望它反映在其他用户之间。如果您不
,这是不可能的一个。持续显式调用 api,
B.使用一些默默地为你调用 api 的库 更新状态(例如,SWR)
c.使用任何发布/订阅模型(例如signalR)
所以,你应该试着先思考和解决第二个问题,它会自动解决第一个问题。