Я работаю над reactjs with redux, чтобы создать приборную панель. Существует функциональность создания вкладки. Я мог бы создать вкладку и отправить rest 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;
}
};
Таб-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>
);
}
}
спасибо за решение для демонстрации вкладки приборной панели. Что касается вкладки, которая будет отображаться сразу после создания вкладки, функция tabChange и функция onSubmit будут использоваться в tab-dialog.js. Я использовал состояние fetchTab, чтобы показать вкладку, как только пользователь ее создаст. – milan
Да, когда пользователь отправляется на сервер, я хочу обновить ту же вкладку и извлечь ее. Например, для каждого пользователя будет отображаться одна вкладка, которая не может быть отредактирована или удалена. Теперь пользователь хочет добавить еще одну вкладку, например вкладку с названием коммерческих устройств, после чего они перейдут на вкладку добавления и создадут название вкладки, называемое коммерческими устройствами, и как только они отправятся на сервер, рекламная кампания должна быть показана вместе с вкладками dasboard и предыдущими добавленными вкладками Если там есть. – milan
Я понимаю редуктор столбца и действия. Но я не понял функцию табуляции. Какая польза от этого, когда уже есть tabsFetch()? Почему 2 функции редуктора используются вкладками и вкладкамиFetch()? – milan