考虑到我的自定义存储,当我尝试使用readItems选择器时,我总是获得默认的存储状态。选择器工作正常(在控制台中使用wp.data.select进行测试),但异步捕获值需要一些时间,我假定useSelect会记住第一个返回的值,这是默认的存储状态,不会响应存储更改。
如何修复此问题?
块编辑功能开始:
const LECTURERS_TABLE = \'tla_mit_lecturers\';
export default function Edit(props) {
const { attributes, setAttributes } = props;
const allItems = useSelect(select => select(\'REST-extra_table\').readItems(LECTURERS_TABLE));
存储:
import apiFetch from \'@wordpress/api-fetch\';
import { createReduxStore, register } from \'@wordpress/data\';
/**
* returns table id from table name
* @param {} table
*/
function getTableId(table) {
if (! table) {
console.log(\'Table name not supplied for API\');
return undefined;
}
const tableId = tableIds.indexOf(table);
if (tableId == -1) {
console.log(\'Wrong table name supplied to the API\');
return undefined;
}
return tableId;
}
// items is array of tables - item[\'table_name\'][index] is individual item
const tableIds = [
\'tla_mit_lecturers\',
]
const DEFAULT_STATE = {
tables: [
[\'default\']
],
};
const actions = {
*createItem( item, table ) {
const tableId = getTableId(table);
const retValue = yield actions.fetchFromAPI(
{
path: \'/extra_table/v1/item?table=\' + table,
method: \'POST\',
data: item
}
);
// retValue should be ID if insert is successful
return retValue ?
{
type: \'CREATE_ITEM\',
item: {ID: retValue, ...item},
tableId
} :
{
type: \'FETCH_ERROR\',
error: \'unknown\'
};
},
*deleteItem( ID, table ) {
const tableId = getTableId(table);
const retValue = yield actions.fetchFromAPI(
{
path: \'/extra_table/v1/item?table=\' + table + \'&ID=\' + ID,
method: \'DELETE\'
}
);
return retValue ?
{
type: \'DELETE_ITEM\',
tableId,
ID
} :
{
type: \'FETCH_ERROR\',
error: \'unknown\'
};
},
*updateItem( ID, item, table ) {
const tableId = getTableId(table);
const retValue = yield actions.fetchFromAPI(
{
path: \'/extra_table/v1/item?table=\' + table + \'&ID=\' + ID,
method: \'PUT\',
data: item
}
);
return retValue ?
{
type: \'UPDATE_ITEM\',
item: {ID, ...item},
ID,
tableId
} :
{
type: \'FETCH_ERROR\',
error: \'unknown\'
};
},
// action to set item values - hydrate in https://unfoldingneurons.com/2020/wordpress-data-store-properties-resolvers
setItem( item, tableId ) {
return {
type: \'SET_ITEM\',
item,
tableId
};
},
// action to set item values - hydrate in https://unfoldingneurons.com/2020/wordpress-data-store-properties-resolvers
setAllItems( items, tableId ) {
return {
type: \'SET_ITEMS\',
items,
tableId
};
},
fetchFromAPI( action ) {
return {
type: \'FETCH_FROM_API\',
path: action.path,
method: action.method,
data: action.data,
tableId: action.tableId
};
}
};
const store = createReduxStore( \'REST-extra_table\', {
reducer( state = DEFAULT_STATE, action ) {
switch ( action.type ) {
case \'CREATE_ITEM\':
return {
...state,
tables: Object.assign([...state.tables], {[action.tableId]: [...state.tables[action.tableId], action.item] })
};
case \'UPDATE_ITEM\':
return {
...state,
tables: Object.assign(
[...state.tables],
{[action.tableId]:
Object.assign(
state.tables[action.tableId],
{[state.tables[action.tableId].findIndex(el => el.ID === action.ID)]: action.item}
)
})
};
case \'DELETE_ITEM\':
return {
...state,
tables: Object.assign([...state.tables], {[action.tableId]: state.tables[action.tableId].filter((el) => el.ID !== action.ID) })
};
// hydrate
case \'SET_ITEM\':
return {
...state,
tables: Object.assign([...state.tables], {[action.tableId]: [...state.tables[action.tableId], action.item] })
}
case \'SET_ITEMS\':
return {
...state,
tables: Object.assign([...state.tables], {[action.tableId]: [...action.items] })
}
case \'FETCH_ERROR\':
console.log(\'AJAX fetch error, code: \' + action.error);
return state;
}
// console.error(\'Table name is not given!!! \'+action.type)
return state;
},
actions,
selectors: {
readItem( state, ID, table ) {
const tableId = getTableId(table);
if (tableId === undefined)
return undefined;
if (state.tables[tableId])
return state.tables[tableId].find(el => el.ID == ID);
else
return undefined;
},
readItems( state, table ) {
const tableId = getTableId(table);
if (tableId === undefined)
return undefined;
// return empty array if state.tables does not exist
if (! state.tables[tableId])
console.error(\'Requested table does not exist in state!\');
return state.tables[tableId] || undefined;
},
},
controls: {
FETCH_FROM_API( action ) {
return apiFetch(
{
path: action.path,
// path: action.path,
method: action.method,
credentials: \'same-origin\',
mode:\'same-origin\',
// headers: {
// \'Content-Type\': \'application/json\'
// },
data: action.data
} );
},
},
resolvers: {
*readItem( ID, table ) {
const tableId = getTableId(table);
const item = yield actions.fetchFromAPI(
{
path: \'/extra_table/v1/item?table=\' + table + \'&ID=\' + ID,
method: \'GET\',
data: null,
tableId
}
);
return item !== undefined ? actions.setItem( item, tableId ) : undefined;
},
*readItems( table ) {
const tableId = getTableId(table);
const allItems = yield actions.fetchFromAPI({
path: \'/extra_table/v1/all_items?table=\' + table,
method: \'GET\',
data: null,
tableId
});
return allItems !== undefined ? actions.setAllItems( allItems, tableId ) : undefined;
},
},
} );
register( store );