我正在使用redux与reactjs一起创建仪表板。有一个创建选项卡的功能。我可以创建一个选项卡并发送到休息api作为POST将其保存在数据库中,但是一旦单击保存按钮,选项卡也应该显示在标题中,而现在没有显示。还有一个名为dashboard(home)的选项卡名称,它作为初始状态传入,必须一直显示。但是只有保存的选项卡显示在标题上,当用户单击保存按钮时不及时刷新页面时也是如此。
简而言之,只有在用户刷新页面时才会显示创建的选项卡。
帮我解决这个问题?
操作
export function addTab(name, icon) {
return (dispatch) => {
dispatch({ type: 'POST_TAB_START' });
return axios({
method: 'POST',
url: '/rest-api/ui/tabs/',
headers: {
'X-CSRFToken': CSRF_TOKEN,
'Content-Type': 'application/json'
},
data: {
name,
icon
},
})
.then((response) => {
dispatch({ type: 'POST_TAB',
payload: response.data });
})
.catch((err) => {
dispatch({ type: 'POST_TAB_FAILURE', payload: err });
});
};
}
export function fetchTabs() {
return dispatch => {
axios.get('/rest-api/ui/tabs/')
.then((response) => {
dispatch({ type: 'RECIEVE_TAB', payload: response.data });
})
.catch((err) => {
dispatch({ type: 'FETCH_TAB_ERROR', payload: err });
});
};
}
减速器
const initial = {
posting: false,
posted: false,
tabs: [],
error: null
};
export const postTab = (state = initial, action) => {
switch (action.type) {
case 'POST_TAB_START':
return { ...state, posting: false };
case 'POST_TAB_FAILURE':
return { ...state, error: action.payload };
case 'POST_TAB':
return { ...state, posting: false, posted: true, tabs: action.payload };
default:
return state;
}
};
const firstState = {
fetching: false,
fetched: true,
tabs: [
{ name: 'dashboard', id: 1, icon: 'dashboard' }
],
error: null,
};
export const fetchTab = (state = firstState, action) => {
switch (action.type) {
case 'RECIEVE_TAB':
return { ...state, fetching: false, fetched: true, tabs: action.payload };
case 'FETCH_TAB_ERROR':
return { ...state, fetching: false, error: action.payload };
default:
return state;
}
};
tab-dialog.js(这是保存标签的表单)
componentWillMount() {
this.props.fetchIcons();
this.props.fetchTabs();
}
onSubmit = (e) => {
e.preventDefault();
this.props.addTab(this.state.name, this.state.icon);
}
renderAddTab() { {/* it is for adding tab from the dialog box */}
const listOfIcon = _.map(this.props.fetchIcon.icons, (icon) => ({
text: icon.name,
id: icon.id,
value: <MenuItem primaryText={icon.name} />
}));
return (
<div className="device-action">
<Dialog
title="Add a Tab"
modal={false}
bodyStyle={{ background: '#fff' }}
contentStyle={customContentStyle}
actionsContainerStyle={{ background: '#fff' }}
titleStyle={{ background: '#fff', color: '#1ab394' }}
open={this.props.createTab.open}
onRequestClose={this.props.closeTabIcon}
>
<form onSubmit={this.onSubmit}>
<div className="tab-name">
<TextField
floatingLabelText="Name"
ref="name"
floatingLabelStyle={{ color: '#1ab394' }}
floatingLabelFocusStyle={{ color: '#1db4c2' }}
underlineStyle={{ borderColor: '#1ab394' }}
onChange={(name) => { this.setState({ name: name.target.value }); }}
/>
</div>
<div className="icon">
<AutoComplete
floatingLabelText="select any icon"
ref="icon"
filter={AutoComplete.noFilter}
openOnFocus
dataSource={listOfIcon}
textFieldStyle={{ borderColor: '#1ab394' }}
className="autocomplete"
onNewRequest={(e) => { this.setState({ icon: e.id }); }}
/>
</div>
<button className="btn">Save</button>
</form>
</Dialog>
</div>
);
}
render() {
const iconSelected = this.props.createTab;
if (!iconSelected) {
return (<span />);
}
if (iconSelected.id === '1') {
return (this.renderDeleteTab());
}
if (iconSelected.id === '2') {
return (this.renderAddTab());
}
}
header.js(此处选项卡应在默认情况下与默认信息中心标签一起显示时显示标签)
class Header extends Component {
componentWillMount() {
this.props.fetchTabs();
}
render() {
const tabs = _.map(this.props.fetchTab.tabs, (tab) =>
<span className="tab" key={tab.id}><a href="">{tab.name}</a></span>
);
const navigation = (
<div className="nav-icon" style={{ margin: '12px 40px 0px 10px' }}>
<i
className="material-icons md-23"
id="1"
onClick={(event) => this.props.selectTabIcon(event)}
>
delete
</i>
<i
className="material-icons md-23"
id="2"
onClick={(event) => this.props.selectTabIcon(event)}
>
add_circle
</i>
</div>
);
return (
<div>
<AppBar
title={tabs}
iconElementRight={navigation}
onLeftIconButtonTouchTap={this.props.handleToggle}
style={{ background: '#fff' }}
/>
</div>
);
}
}
答案 0 :(得分:0)
这会覆盖tabs
州的fetchTab
。
case 'RECIEVE_TAB':
return { ...state, fetching: false, fetched: true, tabs: action.payload };
这样就可以在调度{ name: 'dashboard', id: 1, icon: 'dashboard' }
操作时覆盖您在firstState
中创建的RECIEVE_TAB
。
如果它始终存在,您可能只想将其硬编码到jsx中,但您可以通过以下方式将其添加到仪表板选项卡中:
const dashboardTab = { name: 'dashboard', id: 1, icon: 'dashboard' };
case 'RECIEVE_TAB':
return {
...state,
fetching: false,
fetched: true,
tabs: [dashboardTab, ...action.payload]
};
我无法在您的代码中看到您使用postTab
状态的位置。我冒昧地说你真的只想要一个带有标签的状态,当服务器的帖子成功时你更新了被提取的tab
状态吗?
编辑:
您的Header
组件正在呈现store.fetchTab.tabs
中的标签,但是当您调用addTab
函数时,您正在调度更新您所在州的其他对象的操作{{1} }。你可能只想重新设计你的状态。
减速器
postTab.tabs
动作
const dashboard = { name: 'dashboard', id: 1, icon: 'dashboard' };
const initalTabState = {
tabs: [dashboard],
};
export const tabs = (state = initialTabState, action) => {
switch (action.type) {
case 'TABS_SET':
return {
...state,
tabs: [dashboard, ...action.tabs],
};
case 'TABS_ADD':
return {
...state,
tabs: [...state.tabs, action.tab],
};
case 'TABS_RESET':
return {
...initalTabState,
};
default:
return state;
}
};
const initalTabsPostState = {
posting: false,
posted: false,
error: null,
};
export const tabsPost = (state = initialTabsPostState, action) => {
switch (action.type) {
case 'TABS_POST_START':
return {
...initialTabsPostState,
posting: true,
};
case 'TABS_POST_SUCCESS':
return {
...initialTabsPostState,
posted: true,
};
case 'TABS_POST_FAILURE':
return {
...initialTabsPostState,
error: action.payload,
};
default:
return state;
}
};
const initialTabsFetchState = {
fetching: false,
fetched: true,
error: null,
};
export const tabsFetch = (state = initialTabsFetchState, action) => {
switch (action.type) {
case 'TABS_FETCH_START':
return {
...initialTabsFetchState,
fetching: true,
};
case 'TABS_FETCH_SUCCESS':
return {
...initialTabsFetchState,
fetched: true,
};
case 'TABS_FETCH_FAILURE':
return {
...initialTabsFetchState,
error: action.payload,
};
default:
return state;
}
};