使用react router,我可以使用Link元素来创建由react route本地处理的链接。

我看到它在内部调用this.context.transitionTo(…)。

我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?

我看到了导航混合,但我可以在没有混合的情况下这样做吗?


当前回答

在React Router v4中实现这一点时面临问题的人。

这里有一个从redux操作导航到React应用程序的工作解决方案。

文件history.js

import createHistory from 'history/createBrowserHistory'

export default createHistory()

文件App.js/Route.jsx

import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
 <Route path="/test" component={Test}/>
</Router>

文件*另一个_File.js或redux文件

import history from './history'

history.push('/test') // This should change the URL and rerender Test component

感谢GitHub上的评论:ReactTraining问题评论

其他回答

布局/BaseLayout.jsx

import { Outlet } from "react-router-dom";
import Navbar from "../components/Navbar";

const BaseLayout = () => {
    return(
        <div>
        <Navbar/>
        <Outlet/>
        </div>
    )
}

export default BaseLayout

路由器/index.jsx

import { createBrowserRouter} from "react-router-dom";
import BaseLayout from "../layouts/BaseLayout";
import HomePage from "../views/HomePage";
import Menu from "../components/Menu"
import Detail from "../components/Detail";

const router = createBrowserRouter([
    {
        element: <BaseLayout/>,
        children:[
            {
                path: "/",
                element: <Menu />,
            },
            {
                path: '/:id',
                element: <Detail/>
            }
        ]

    },
])

export default router

存储/actionType.js

export const FETCH_DATA_FOODS = "food/setFood"

export const FETCH_DATA_FOODS_DETAILS = "food/setDetailFood"

存储/还原器/还原器.js

import { FETCH_DATA_FOODS, FETCH_DATA_FOODS_DETAILS } from "../actionType";

const initialState = {
    foods:[],
    detailFood:{}
};

const foodReducer = (state = initialState, action) => {
    switch(action.type){
        case FETCH_DATA_FOODS:
            return{
                ...state,
                foods: action.payload
            }
        case FETCH_DATA_FOODS_DETAILS:
            return{
                ...state,
                detailFood: action.payload
            }
        default:
            return state
    }
}

export default foodReducer

存储/actionCreator

import { FETCH_DATA_FOODS, FETCH_DATA_FOODS_DETAILS } from "./actionType";

// import { FETCH_DATA_FOODS } from "../actionType";
export const actionFoodSetFoods = (payload) => {
  return {
    type: FETCH_DATA_FOODS,
    payload,
  };
};

export const actionDetailSetDetailFood = (payload) => {
  return {
    type: FETCH_DATA_FOODS_DETAILS,
    payload,
  };
};

export const fetchDataFoods = () => {
  return (dispatch, getState) => {
    fetch("https://maxxkafe.foxhub.space/users")
      .then((response) => {
        if (!response.ok) {
          throw new Error("notOk");
        }
        return response.json();
      })
      .then((data) => {
        // dispatcher({
        //     type: "food/setFood",
        //     payload: data
        // })

        dispatch(actionFoodSetFoods(data));
      });
  };
};

export const fetchDetailDataFood = (id) => {
  return (dispatch, getState) => {
    console.log(id);
    fetch(`https://maxxkafe.foxhub.space/users/${id}`)
      .then((response) => {
        if (!response.ok) {
          throw new Error("gaOkNich");
        }
        console.log(response, ",,,,,,,,");
        return response.json();
      })
      .then((data) => {
        dispatch(actionDetailSetDetailFood(data));
      });
  };
};

stores/index.js

import { legacy_createStore as createStore, combineReducers, applyMiddleware } from 'redux'
import foodReducer from './reducers/foodReducer'
import thunk from "redux-thunk"

const rootReducer = combineReducers({
    foods: foodReducer
});

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store

应用程序.js

import { RouterProvider } from "react-router-dom";
import router from "./routers";
import { Provider } from "react-redux";
import store from "./stores";

const App = () => {
  return (
    <Provider store={store}>
      <RouterProvider router={router} />
    </Provider>
  );
};

export default App;

组件/类别.jsx

import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import { fetchDataCategories } from "../stores/actionCreate";
import RowCategory from "../views/rowTableCategory";

const Category = () => {
  // const [categories, setCategories] = useState([])
  const { categories } = useSelector((state) => state.categories);
  const dispatcher = useDispatch();
  useEffect(() => {
    // fetch("http://localhost:3003/categories")
    // .then((response) => {
    //     if(!response.ok){
    //         throw new Error ("gaOkNich")
    //     }
    //     return response.json()
    // })
    // .then((data) => {
    //     setCategories(data)
    // })
    dispatcher(fetchDataCategories());
  }, []);
  return (
    <section className="mt-12">
      <div className="flex mr-20 mb-4">
        <Link to={'/add-Form'} className="flex ml-auto text-white bg-red-500 border-0 py-2 px-6 focus:outline-none hover:bg-red-600 rounded">
          Create Category
        </Link>
      </div>
      <div className="overflow-hidden rounded-lg border border-gray-200 shadow-md m-5">
        <table className="w-full border-collapse bg-white text-left text-sm text-gray-500">
          <thead className="bg-gray-50">
            <tr>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Name
              </th>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Created At
              </th>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Updated At
              </th>
              <th
                scope="col"
                className="px-6 py-4 font-medium text-gray-900"
              ></th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-100 border-t border-gray-100">
            {categories.map((el) => {
              return <RowCategory key={el.id} el={el} />;
            })}
          </tbody>
        </table>
      </div>
    </section>
  );
};

export default Category;

组件/login.jsx

import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { fetchDataFoods, login } from "../stores/actionCreate";

const Login = () => {
  const input = {
    email: "",
    password: "",
  };
  const [values, setValues] = useState(input);
  // const [password, setPassword] = useState('')
  // const {admin} = useSelector((state) => state.admin)

  const dispatcher = useDispatch();
  const movePage = useNavigate();

  const handleChange = (event) => {
    const { name, value } = event.target;
    setValues({
      ...values,
      [name]: value,
    });
    console.log(value);
  };

  const handleLogin = async (event) => {
    event.preventDefault();
    try {
      await dispatcher(login(values));
      await dispatcher(fetchDataFoods());
      movePage("/home");
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <section className="font-mono bg-white-400 mt-[10rem]">
      <div className="container mx-auto">
        <div className="flex justify-center px-6 my-12">
          <div className="w-full xl:w-3/4 lg:w-11/12 flex justify-center">
            <div className="w-full lg:w-7/12 bg-white p-5 rounded-lg lg:rounded-l-none">
              <h3 className="pt-4 text-2xl text-center">Login Your Account!</h3>
              <form
                className="px-8 pt-6 pb-8 mb-4 bg-white rounded"
                onSubmit={handleLogin}
              >
                <div className="mb-4">
                  <label
                    className="block mb-2 text-sm font-bold text-gray-700"
                    htmlFor="email"
                  >
                    Email
                  </label>
                  <input
                    className="w-full px-3 py-2 mb-3 text-sm leading-tight text-gray-700 border rounded shadow appearance-none focus:outline-none focus:shadow-outline"
                    id="email"
                    type="email"
                    name="email"
                    placeholder="Email"
                    // onChange={(event) => setValues({email: event.target.value})}
                    onChange={handleChange}
                    value={values.email.email}
                  />
                </div>

                <div className="mb-4 md:flex md:justify-between">
                  <div className="mb-4 md:mr-2 md:mb-0">
                    <label
                      className="block mb-2 text-sm font-bold text-gray-700"
                      htmlFor="password"
                    >
                      Password
                    </label>
                    <input
                      className="w-full px-3 py-2 mb-3 text-sm leading-tight text-gray-700 border  rounded shadow appearance-none focus:outline-none focus:shadow-outline"
                      id="password"
                      type="password"
                      name="password"
                      placeholder="Password"
                      onChange={handleChange}
                      value={values.password}
                      // onChange={(event) => setValues({password: event.target.value})}
                    />
                  </div>
                </div>
                <div className="mb-4 md:flex md:justify-between"></div>
                <div className="mb-6 text-center">
                  <button
                    className="w-full px-4 py-2 font-bold text-white bg-blue-500 rounded-full hover:bg-blue-700 focus:outline-none focus:shadow-outline"
                    type="submit"
                  >
                    Login
                  </button>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};
export default Login;

对于ES6+React组件,以下解决方案适用于我。

我跟随费利佩·斯金纳,但添加了一个端到端解决方案,以帮助像我这样的初学者。

以下是我使用的版本:

“反应路由器”:“^2.7.0”“反应”:“^15.3.1”

下面是我的react组件,其中我使用react路由器进行编程导航:

import React from 'react';

class loginComp extends React.Component {
   constructor( context) {
    super(context);
    this.state = {
      uname: '',
      pwd: ''
    };
  }

  redirectToMainPage(){
        this.context.router.replace('/home');
  }

  render(){
    return <div>
           // skipping html code 
             <button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
    </div>;
  }
};

 loginComp.contextTypes = {
    router: React.PropTypes.object.isRequired
 }

 module.exports = loginComp;

以下是路由器的配置:

 import { Router, Route, IndexRedirect, browserHistory } from 'react-router'

 render(<Router history={browserHistory}>
          <Route path='/' component={ParentComp}>
            <IndexRedirect to = "/login"/>
            <Route path='/login' component={LoginComp}/>
            <Route path='/home' component={HomeComp}/>
            <Route path='/repair' component={RepairJobComp} />
            <Route path='/service' component={ServiceJobComp} />
          </Route>
        </Router>, document.getElementById('root'));

在基于类的组件中编程导航。

import { Redirect } from "react-router-dom";

class MyComponent extends React.Component{
    state = {rpath: null}

    const goTo = (path) => this.setState({rpath: path});

    render(){
        if(this.state.rpath){
            return <Redirect to={this.state.rpath}/>
        }
        .....
        .....
    }
}

只需使用useNavigate from react router dom

import { useNavigate } from "react-router-dom";

const MYComponent = () => {
    const navigate = useNavigate();

    navigate("Xyz/MYRoutes");

 
}

export default MYComponent;

在代码中使用上述的useNavigate功能。

在写作时,正确的答案适合我

this.context.router.history.push('/');

但您需要将PropTypes添加到组件中

Header.contextTypes = {
  router: PropTypes.object.isRequired
}
export default Header;

不要忘记导入PropTypes

import PropTypes from 'prop-types';