shio-max
@shio-max (Riooo)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

dispatch(push("/"))でページ遷移できない

解決したいこと

react, redux, firebaseで 作業管理アプリを作成しています。こちらのECアプリを参考にしてます
新規登録するタスクリストを 保存ボタンのイベント関数(operations.js内のsaveTask関数)で、firestoreにデータを保存する非同期処理がはしり、その後 dispatch(push("/"))でホームページに戻る処理をしたいのですが、
非同期処理が成功したところまでは確認できますが、
dispatchで再び、タスクリスト(EditTaskListjsx)のページコンポーネントの処理がはしり、idがundefinedで遷移ができずに、困っています。

発生している問題・エラー

Cannot read property 'split' of undefined

新規作成時は、idは空で、operations.js内の処理で firestoreの自動採番されるidをそのまま渡しています。
dispatch(push)がはしると、そのidがundefiendになっています。
スクリーンショット 2021-05-16 午後11.08.06.png

該当するソースコード

EditTaskList.jsx
const EditTaskList = () => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const selector = useSelector((state) => state);
  const uid = getUserId(selector);

  //URL末尾の:idにあたる部分の文字列を抽出,これが Cloud Firestore の tasklist docのid に対応
  //const path = selector.router.location.pathname;
  //console.log(path); /task/edit
  //let id = path.split("/task/edit")[1];
  let id = window.location.pathname.split("/task/edit")[1];
  console.log(id, "新規作成時");

  //編集時
  if (id !== "") {
    id = id.split("/")[1];
    console.log(id, "編集時");
  }

  const [selectedDate, setSelectedDate] = useState(new Date());
  const [items, setItems] = useState([]);
  const [note, setNote] = useState("");



  //編集のとき
  useEffect(() => {
    if (id !== "") {
      db.collection("users")
        .doc(uid)
        .collection("tasklist")
        .doc(id)
        .get()
        .then((snapshot) => {
          const data = snapshot.data();
          console.log(data);
          setSelectedDate(data.selectedDate.toDate());
          setItems(data.items);
          setNote(data.note);
        });
    }
  }, [uid, id]);

  return (
     //関係しないコード省略してます

          <Button
            onClick={() => {
              dispatch(saveTaskList(id, selectedDate, items, note));
            }}
          >
            作業リストを保存
          </Button>
  );
};
operations.js
export const saveTaskList = (id, selectedDate, items, note) => {
  return async (dispatch, getState) => {
    const timestamp = FirebaseTimestamp.now();
    const uid = getState().users.uid;

    const data = {
      selectedDate: selectedDate,
      items: items,
      note: note,
      updated_at: timestamp,
    };

    //新規作成時 idを発行
    if (id === "") {
      const tasklistRef = db
        .collection("users")
        .doc(uid)
        .collection("tasklist")
        .doc();
      id = tasklistRef.id;
      data.id = id;
      data.created_at = timestamp;
      console.log(id, "採番された後");
    }

    return db
      .collection("users")
      .doc(uid)
      .collection("tasklist")
      .doc(id)
      .set(data, { merge: true })
      .then(() => {
        console.log("secucessd!!");
        //console.log(dispatch(push));
        //{type: "@@router/CALL_HISTORY_METHOD", payload: {…}}
        dispatch(push("/"));
      })
      .catch((error) => {
        alert("データの保存に失敗しました。");

        const errorMessage = error.message;
        console.log(errorMessage);
      });
  };
};
store.js
//redux 関連
import {
  createStore as reduxCreateStore,
  combineReducers,
  applyMiddleware,
} from "redux";
//router関連
import { connectRouter, routerMiddleware } from "connected-react-router";
//react-thunk関連(非同期処理を制御するライブラリ)
import thunk from "redux-thunk";
//reducers関連
import { UsersReducer } from "../users/reducers";

export default function createStore(history) {
  //reduxのメゾットを使用
  return reduxCreateStore(
    combineReducers({
      router: connectRouter(history),
      users: UsersReducer,
    }),
    applyMiddleware(routerMiddleware(history), thunk)
  );
}
Router.jsx
const Router = () => {
  return (
    <Switch>
      <Route exact path="/signin/reset" component={Reset} />
      <Route exact path="/signin" component={SignIn} />
      <Route exact path="/signup" component={SignUp} />
      <Auth>
        <Route exact path={"(/)?"} component={Home} />
        <Route path={"/task/edit(/:id)?"} component={EditTaskList} />
      </Auth>
    </Switch>
  );
};
index.jsx
ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    </ConnectedRouter>
  </Provider>,
  document.getElementById("root")
);

自分で試したこと

history をインポートして、 history.push("/")を試しても、同じエラーになりました。
ルーターが絡んでいるのですかね、、認証機能でのページ遷移などはできています。

何かアドバイス、ご指摘あれば、お願いします!!

0

1Answer

Router.jsxのEditTaskListのRouteタグのところにexactがついてないので、Homeに遷移した場合もEditTaskListがレンダリングされているのだと思います。

0Like

Comments

  1. @shio-max

    Questioner

    試しましたが、 同じエラーになります。

Your answer might help someone💌