クエリパラメータを変更した後、なぜデフォルトルートが表示されるのかよくわかりません。この種の問題に対するより良いアプローチはありますか?多分私はクエリパラメータを使用すべきではありませんか?教育を受けるために開いてください!
バージョン "react": "^ 16.2.0"、 "react-dom": "^ 16.2.0"、 "react-router": "^ 4.2.0"、 "react-router-dom": "^ 4.2。 2 "、
テストケース https://codepen.io/adamchenwei/pen/YeJBxY?editors=0011
再現手順クリックホーム->ステップ1
予想される動作ステップ1とステップ2に進むと、正しいdomがレンダリングされます
実際の動作は空、ページには何も表示されません
// For this demo, we are using the UMD build of react-router-dom
const {
BrowserRouter,
Switch,
Route,
Link
} = ReactRouterDOM
const {
Component,
} = React;
const Router = BrowserRouter;
const Step1View = () => (
<div>
<h1> Step 1</h1>
</div>
)
const Step2View = () => (
<div>
<h1> Step 2</h1>
</div>
)
class Home extends Component {
constructor(props) {
super(props);
console.log('-!!!')
this.state = {
step: 1,
}
this.next = this.next.bind(this);
}
next(stepNumber=1) {
this.props.history.Push({
pathname: `/adamchenwei/pen/YeJBxY?editors=0011/?step=${stepNumber}`,
});
const query = this.props.history.location.pathname;
console.log('---aaaaa');
console.log(query);
if (query === '/adamchenwei/pen/YeJBxY?editors=0011/?step=1') {
this.setState({
step: 1,
})
} else if (query === '/adamchenwei/pen/YeJBxY?editors=0011/?step=2') {
this.setState({
step: 2,
})
}
}
render() {
console.log('render!!!');
console.log(this);
const {
step
} = this.state;
console.log('---step');
console.log(step);
return(
<div>
<h1>Welcome to the Tornadoes Website!</h1>
<button onClick={()=> this.next(1)} > Step 1</button>
<button onClick={()=> this.next(2)} > Step 2</button>
{
step === 1 ? <h1>Step 1 here</h1> : null
}
{
step === 2 ? <h1>Step 2 here</h1> : null
}
</div>
);
}
}
// The Main component renders one of the three provided
// Routes (provided that one matches). Both the /roster
// and /schedule routes will match any pathname that starts
// with /roster or /schedule. The / route will only match
// when the pathname is exactly the string "/"
const Main = () => (
<main>
<Route exact path='/' component={Home}/>
</main>
)
// The Header creates links that can be used to navigate
// between routes.
const Header = () => (
<header>
<nav>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/roster'>Roster</Link></li>
<li><Link to='/schedule'>Schedule</Link></li>
</ul>
</nav>
</header>
)
const App = () => (
<div>
<Header />
<Main />
</div>
)
// This demo uses a HashRouter instead of BrowserRouter
// because there is no server to match URLs
ReactDOM.render((
<Router>
<App />
</Router>
), document.getElementById('root'))
V4以降のReactルーターは、ロケーションオブジェクトにクエリパラメータを提供しなくなりました。その理由は
クエリ文字列parsing/stringifying
をわずかに異なる方法で実行する人気のあるパッケージがいくつかあり、これらの各違いは、一部のユーザーにとっては"correct"
の方法であり、他のユーザーにとっては"incorrect"
の方法です。 React Router
が"right"
を選んだ場合、それは一部の人にのみ適しています。次に、他のユーザーが自分の好みのクエリ解析パッケージを置き換える方法を追加する必要があります。 Reactによる検索文字列の内部使用はなく、Key-Valueペアを解析する必要があるため、これらのどれが「正しい」かを選択する必要はありません。 」.
それが含まれていると、クエリオブジェクトを期待しているビューコンポーネントのlocation.search
を解析するだけの方が理にかなっています。
これを一般的に行うには、react-routerからwithRouterをオーバーライドします。
customWithRouter.js
import { compose, withPropsOnChange } from 'recompose';
import { withRouter } from 'react-router';
import queryString from 'query-string';
const propsWithQuery = withPropsOnChange(
['location', 'match'],
({ location, match }) => {
return {
location: {
...location,
query: queryString.parse(location.search)
},
match
};
}
);
export default compose(withRouter, propsWithQuery)
クエリ文字列が必要な場合は、次のように使用できます
import withRouter from 'path/to/customWithRouter.js';
class Home extends Component {
constructor(props) {
super(props);
console.log('-!!!')
this.state = {
step: 1,
}
this.next = this.next.bind(this);
}
next(stepNumber=1) {
this.props.history.Push({
pathname: `/adamchenwei/pen/YeJBxY?editors=0011&step=${stepNumber}`,
});
}
componentDidUpdate(prevProps) { // using componentDidUpdate because componentWillReceiveProps will be renamed to UNSAFE_componentWillReceiveProps from v16.3.0 and later removed
const {query: { step } } = this.props.history.location;
if(!_.isEqual(this.props.history.location.query, prevProps.history.location.query)) {
this.setState({
step
})
}
}
render() {
console.log('render!!!');
console.log(this);
const {
step
} = this.state;
console.log('---step');
console.log(step);
return(
<div>
<h1>Welcome to the Tornadoes Website!</h1>
<button onClick={()=> this.next(1)} > Step 1</button>
<button onClick={()=> this.next(2)} > Step 2</button>
{
step === 1 ? <h1>Step 1 here</h1> : null
}
{
step === 2 ? <h1>Step 2 here</h1> : null
}
</div>
);
}
}
const HomeWithQuery = withRouter(Home);
// A lose explanation. URL = localhost:3000/myRoute/2
<Router history={history}>
<Route path="/myRoute/:id" component={App} />
</Router>
class App extends Component {
render() {
const { id } = this.props.match.params
return (
<div>
{id === 2 ? <div>id is 2</div> : <div>id not 2</div>}
</div>
)
}
}