简体   繁体   中英

Change URl tabs without page refresh NEXT.JS

I'm using material ui tabs, and I'm pushing the tabs to URL. I want to push the tab but not refresh the page every-time I change the tab. Here is my code, and I'm using shallow:true but the problem remains:

const tabs = [
  { label: 'Details', value: 'details' },
  { label: 'Purchases', value: 'purchases' },
  { label: 'Money Transfer', value: 'moneyTransfer' },
  {label:'User Activity',value:'userActivity'},
  {label:'User Logs',value:'userLogs'}
];
const {
    query: { UsersId,tab },
  } = router
const handleTabsChange = (event: ChangeEvent<{}>, value: string): void => {

  router.push({
    pathname: `/dashboard/twigUsers/${UsersId}`,query: { tab:value}},undefined,{ shallow: true });
};

             <Tabs
              indicatorColor="primary"
              onChange={handleTabsChange}
              scrollButtons="auto"
              sx={{ mt: 3 }}
              textColor="primary"
              value={tab}
              variant="scrollable"
            >
              {tabs.map((tab) => (
                <Tab
                  key={tab.value}
                  label={tab.label}
                  value={tab.value}
                />
              ))}
            </Tabs>

{tab === 'details' && (
             <UsersDetailsContainer user={user} userId={UsersId}/>
            )}
            {tab === 'purchases' && <PurchasesListTable userDetailsId={userDetailsId}/>}
            {tab === 'moneyTransfer' && <MoneyTransferListTable userDetailsIdMT={userDetailsIdMT} />}
            {tab==='userActivity' &&<UserActivity/>}
            {tab==='userLogs' &&<UserLogs user={user} userId={twigUsersId}/>}

You need to prevent propagation, else this will actually just propagate to the parent, and will refresh the site.

const handleTabsChange = (event: ChangeEvent<{}>, value: string): void => {
  event.preventDefault();

  router.push(
    {
      pathname: `/dashboard/twigUsers/${UsersId}`,
      query: { tab: value },
    },
    undefined,
    { shallow: true }
  );
};

check out an implementation in action here

I have changed the whole logic in order to work, I have stored the tabs in redux saga here is the code: Redux part

// utils
import axios from 'axios';
import produce from 'immer';
import creator from '../../../utils/actionCreator';
import { put, takeLatest } from 'redux-saga/effects';
import { AnyAction } from 'redux';

// consts
export const REQUEST = '@app/tabs/get/getUsersDetailsTabs/REQUEST';
export const SUCCESS = '@app/tabs/get/getUsersDetailsTabs/SUCCESS';
export const FAILURE = '@app/tabs/get/getUsersDetailsTabs/FAILURE';

export const UPDATE_REQUEST = '@app/tabs/get/getUsersDetailsTabs/UPDATE_REQUEST';
export const UPDATE_SUCCESS = '@app/tabs/get/getUsersDetailsTabs/UPDATE_SUCCESS';
export const UPDATE_FAILURE = '@app/tabs/get/getUsersDetailsTabs/UPDATE_FAILURE';
export const CLEAR = '@app/tabs/get/getUsersDetailsTabs/CLEAR';

// initial state
const initalState = {
  error: '',
  loading: false,
  success: false,
  tabs:[]
};

// reducer
const reducer = (state = initalState, { payload, ...action }: AnyAction) =>
  produce(state, (draft) => {
    switch (action.type) {
      case REQUEST:
        draft.tabs = payload;
        break;
      case SUCCESS:
        draft.loading = false;
        draft.tabs = payload;
        break;
      case FAILURE:
        draft.loading = false;
        draft.error = payload;
        break;
      case UPDATE_REQUEST:
        draft.loading = true;
        break;
      case UPDATE_SUCCESS:
        draft.loading = false;
        draft.success = true;
        break;
      case UPDATE_FAILURE:
        draft.loading = false;
        draft.error = payload;
        break;
      case CLEAR:
        draft.loading = false;
        draft.error = '';
        draft.tabs = [];
        break;
      default:
        break;
    }
  });

// actions
const actions = {
  request: (tabs) => creator(REQUEST, tabs),
  success: (tabs) => creator(SUCCESS, tabs),
  failure: (tabs) => creator(FAILURE, tabs),

  updateRequest: (tabs) => creator(UPDATE_REQUEST, tabs),
  updateSuccess: (tabs) => creator(UPDATE_SUCCESS, tabs),
  updateFailure: (tabs) => creator(UPDATE_FAILURE, tabs),

  clear: () => creator(CLEAR)
};

// sagas
const sagas = {
    *getTabs(tabs){
    return{
        type:REQUEST,
        payload:tabs
    }
    }
};

// watcher
const watcher = function* watch() {
  yield takeLatest(REQUEST, sagas.getTabs);
};

// exports
export { actions, watcher };
export default reducer;

Dispatch the tabs

const [value, setValue] = useState('details');
const handleTabsChange = (event: ChangeEvent<{}>,newValue): void => {
   console.log(newValue,"new value")
  setValue(newValue);
};
useEffect(() => {
    dispatch(getTabs.request(
      [ { label: 'Details', value: 'details' },
      { label: 'Purchases', value: 'purchases' },
      { label: 'Money Transfer', value: 'moneyTransfer' },
      {label:'User Activity',value:'userActivity'},
      {label:'User Logs',value:'userLogs'}]
    ));
  },[]);
  const { tabs:tabs } = useSelector((state: RootStateOrAny) => state.tabs); 

Tabs

  <Tabs
              indicatorColor="primary"
              onChange={handleTabsChange}
              scrollButtons="auto"
              sx={{ mt: 3 }}
              textColor="primary"
              value={value}
              variant="scrollable"
            >
              {tabs.map((tab) => (
                <Tab
                  key={tab.value}
                  label={tab.label}
                  value={tab.value}
                />
              ))}
            </Tabs>

{value === 'details' && (
             <UsersDetailsContainer user={user} userId={twigUsersId}/>
            )}
            {value === 'purchases' && <PurchasesListTable userDetailsId={userDetailsId}/>}
            {value === 'moneyTransfer' && <MoneyTransferListTable userDetailsIdMT={userDetailsIdMT} />}
            {value==='userActivity' &&<UserActivity/>}
            {value==='userLogs' &&<UserLogs user={user} userId={twigUsersId}/>}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM