2016-10-12 66 views
0

我正在与reactxs与redux创建仪表板。有一个创建选项卡的功能。我可以创建一个选项卡并发送到静态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> 
    ); 
    } 
} 

enter image description here

回答

0

这是覆盖你tabsfetchTab状态。

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功能你调度,在你的状态,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; 
    } 
}; 

动作

export function addTab(name, icon) { 
    return (dispatch) => { 
    dispatch({ type: 'TABS_POST_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: 'TABS_POST_SUCCESS' }); 
     dispatch({ type: 'TABS_ADD', tab: response.data }); 
    }) 
    .catch((err) => { 
     dispatch({ type: 'TABS_POST_FAILURE', payload: err }); 
    }); 
    }; 
} 

export function fetchTabs() { 
    return (dispatch) => { 
    dispatch({ type: 'TABS_FETCH_START' }); 
    return axios.get('/rest-api/ui/tabs/') 
     .then((response) => { 
     dispatch({ type: 'TABS_FETCH_SUCCESS' }) 
     dispatch({ type: 'TABS_SET', tabs: response.data }); 
     }) 
     .catch((err) => { 
     dispatch({ type: 'TABS_FETCH_FAILURE', payload: err }); 
     }); 
    }; 
} 
+0

感谢用于示出的仪表板标签中的溶液。关于选项卡在创建选项卡后立即显示,onChange函数和onSubmit函数在tab-dialog.js中使用。我用fetchTab状态在用户创建它时立即显示标签。 – milan

+0

是的当用户发布到服务器我想要更新相同的选项卡并获取它。例如,对于不能编辑或删除的仪表板的用户来说将会有一个选项卡。现在用户想要添加另一个选项卡,例如名为commercial devices的选项卡,然后他们将添加选项卡并创建一个名为commercial devices的选项卡名称,并且一旦他们发布到服务器选项卡广告应该与dasboard和先前添加的选项卡一起显示如果有。 – milan

+0

我了解帖子标签减速器和操作。但我不明白标签功能。当有tabsFetch()时,那有什么用?为什么使用2个reducer函数tab和tabsFetch()? – milan

相关问题