programing

react-reason - 처리기 구성 요소에 전달

prostudy 2022. 3. 19. 12:47
반응형

react-reason - 처리기 구성 요소에 전달

나는 Ract Router를 사용하는 React.js 응용 프로그램에 대해 다음과 같은 구조를 가지고 있다.

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var Index = React.createClass({
  render: function () {
    return (
        <div>
            <header>Some header</header>
            <RouteHandler />
        </div>
    );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});

몇 가지 속성을 에 전달하고 싶다.Comments구성 요소

(보통 나는 이렇게 할 것이다.<Comments myprop="value" />)

라우터 리액션으로 가장 쉽고 올바른 방법을 선택하십시오.

포장지를 쓰지 않는 것이 좋겠다면 이렇게 해도 될 것 같다.

class Index extends React.Component { 

  constructor(props) {
    super(props);
  }
  render() {
    return (
      <h1>
        Index - {this.props.route.foo}
      </h1>
    );
  }
}

var routes = (
  <Route path="/" foo="bar" component={Index}/>
);

갱신하다

신작 출시 이후, 소품들을 직접 통해 전달이 가능하다.Route구성 요소, 래퍼를 사용하지 않음.예를 들어, 소품 사용.

구성 요소:

class Greeting extends React.Component {
  render() {
    const {text, match: {params}} = this.props;

    const {name} = params;

    return (
      <React.Fragment>
        <h1>Greeting page</h1>
        <p>
          {text} {name}
        </p>
      </React.Fragment>
    );
  }
}

사용량:

<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />

코드 및 상자 예제


이전 버전

내가 선호하는 방법은 포장하는 것이다.Comments구성 요소 및 포장지를 경로 처리기로 전달하십시오.

변경 사항이 적용된 예:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var CommentsWrapper = React.createClass({
  render: function () {
    return (
      <Comments myprop="myvalue"/>
    );
  }
});

var Index = React.createClass({
  render: function () {
    return (
      <div>
        <header>Some header</header>
        <RouteHandler/>
      </div>
    );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={CommentsWrapper}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});

승인된 응답에서 코리안틱에 의한 주석에서 복사:

<Route path="comments" component={() => (<Comments myProp="value" />)}/>

이것이 내 의견으로는 가장 우아한 해결책이다.그건 효과가 있다.나를 도와주었다.

이것은 Rajesh유지가 불편한 코멘트를 하지 않고 Ract Router 4로 업데이트한 해결책이다.

코드는 다음과 같을 것이다.

<Route path="comments" render={(props) => <Comments myProp="value" {...props}/>}/>

내가 사용하는 참고 사항render대신에component그 이유는 원치 않는 재마운트를 피하기 위함이다.나는 또한 그 일을 통과한다.props코멘트 구성요소에 객체 스프레드 운영자(ES7 제안서)와 동일한 소품을 사용한다.

콜치의 대답에 따른 후속 조치일 뿐이야.구성요소의 포장을 추상화하는 것은 매우 쉽다.

var React = require('react');

var wrapComponent = function(Component, props) {
  return React.createClass({
    render: function() {
      return React.createElement(Component, props);
    }
  });
};

<Route path="comments" handler={wrapComponent(Comments, {myprop: value})}/>

나는 아직 이 솔루션을 테스트하지 않았기 때문에 어떤 피드백도 중요하다.

이 방법을 사용하면 라우터를 통해 전송되는 모든 소품(예: 매개 변수)을 덮어쓰거나 제거할 수 있다는 점에 유의하십시오.

소품 전달은 소품 전달이 가능하다.<RouteHandler> 또는 v0.13).x의 경우) 또는 v1.0의 Route 구성 요소 자체;

// v0.13.x
<RouteHandler/>
<RouteHandler someExtraProp={something}/>

// v1.0
{this.props.children}
{React.cloneElement(this.props.children, {someExtraProp: something })}

(https://github.com/rackt/react-router/releases/tag/v1.0.0)의 업그레이드 가이드 참조)

모든 어린이 취급자는 동일한 소품 세트를 받게 된다. 상황에 따라 유용하거나 그렇지 않을 수 있다.

ES6를 사용하면 구성 요소 래퍼를 인라인으로 만들 수 있다.

<Route path="/" component={() => <App myProp={someValue}/>} >

자녀를 합격시켜야 하는 경우:

<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >

반응로터 v4 알파

이제 이전 방법과 매우 유사하지만, 이것을 하기 위한 새로운 방법이 있다.

import { Match, Link, Miss } from 'react-router';
import Homepage from './containers/Homepage';

const route = {
    exactly: true,
    pattern: '/',
    title: `${siteTitle} - homepage`,
    component: Homepage
  }

<Match { ...route } render={(props) => <route.component {...props} />} />

P.S. 이것은 알파 버전에서만 작동하며 v4 알파 릴리스 후에 제거되었다.v4 최신 버전에서 는 다시 한번, 경로와 정확한 소품들을 가지고 있다.

react-react-reason 예제 앱은 react-reason-4 지점의 routes.js에서 정확히 이 작업을 수행하는 코드를 포함하고 있다.

내가 생각해 낸 가장 깨끗한 솔루션(Ract Router v4):

<Route
  path="/"
  component={props => <MyComponent {...props} foo="lol" />}
/>

MyComponent아직 가지고 있다props.match그리고props.location, 그리고 가지고 있다.props.foo === "lol".

상태 비저장 함수 구성 요소로 포장:

<Router>
  <Route 
    path='/' 
    component={({children}) => 
      <MyComponent myProp={'myVal'}>{children}</MyComponent/>
    }/>
</Router>

또한 RouteHandler mixin을 사용하여 래퍼 구성요소를 피하고 보다 쉽게 부모 상태를 소품으로 전달할 수 있다.

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var RouteHandler = require('react-router/modules/mixins/RouteHandler');

var Index = React.createClass({
      mixins: [RouteHandler],
      render: function () {
        var handler = this.getRouteHandler({ myProp: 'value'});
        return (
            <div>
                <header>Some header</header>
                {handler}
           </div>
        );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});

소품들을 지나다닐 수 있다.<RouterHandler/>다음과 같은 경우:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var Index = React.createClass({
  render: function () {
    var props = this.props; // or possibly this.state
    return (
        <div>
            <header>Some header</header>
            <RouteHandler {...props} />
        </div>
    );
  }
});

이것의 단점은 당신이 소품을 무분별하게 전달하고 있다는 것이다.그렇게Comments경로 구성에 따라 실제로 다른 구성요소를 위한 소품을 받게 될 수 있다.이후론 별일 아니다.props불변하지만, 두 개의 다른 구성 요소가 이름이 붙은 소품을 기대한다면 이것은 문제가 될 수 있다.foo하지만 다른 가치관을 가지고 있다.

1.0 및 2.0에서 사용할 수 있음createElement의 소품.Router대상 요소를 만드는 정확한 방법을 지정하십시오.문서 출처

function createWithDefaultProps(Component, props) {
    return <Component {...props} myprop="value" />;
}

// and then    
<Router createElement={createWithDefaultProps}>
    ...
</Router>

라우터 v 4 솔루션 반응

오늘 아침에 우연히 이 질문을 발견했는데, 여기 내가 사용하는 패턴이 있다.바라건대 이것은 보다 최신의 해결책을 찾는 누구에게나 유용하다.

이것이 최선의 해결책인지는 잘 모르겠지만, 이것이 나의 현재 패턴이다.일반적으로 사용하는 구성 요소(로더, 모델 등)를 관련 구성과 함께 보관하는 Core 디렉터리가 있으며 다음과 같은 파일을 포함하고 있다.

import React from 'react'
import { Route } from 'react-router-dom'

const getLocationAwareComponent = (component) => (props) => (
  <Route render={(routeProps) => React.createElement(component, 
{...routeProps, ...props})}/>
)

export default getLocationAwareComponent

그러면 문제의 파일에서 다음과 같이 하겠다.

import React from 'react'
import someComponent from 'components/SomeComponent'
import { getLocationAwareComponent } from 'components/Core/getLocationAwareComponent'
const SomeComponent = getLocationAwareComponent(someComponent)

// in render method:
<SomeComponent someProp={value} />

내가 컴포넌트의 기본 수출품을 작은 낙타케이스로 수입하는 것을 알 수 있을 겁니다. 캐멀케이스에 있는 새로운 위치 인식 컴포넌트의 이름을 붙여서 정상적으로 사용할 수 있도록 하는 겁니다.추가 가져오기 라인과 할당 라인 외에 구성 요소는 예상대로 동작하며 모든 경로 소품이 추가되어 모든 소품을 정상적으로 수신한다.따라서, 나는 이.props를 통해 구성요소 수명주기 방법으로부터 행복하게 방향을 바꿀 수 있다.history.properties 위치 확인 등

이것이 도움이 되기를!

또한 es6와 상태 비저장 기능을 결합하여 훨씬 더 깨끗한 결과를 얻을 수 있다.

import Dashboard from './Dashboard';
import Comments from './Comments';

let dashboardWrapper = () => <Dashboard {...props} />,
    commentsWrapper = () => <Comments {...props} />,
    index = () => <div>
        <header>Some header</header>
        <RouteHandler />
        {this.props.children}
    </div>;

routes = {
    component: index,
    path: '/',
    childRoutes: [
      {
        path: 'comments',
        component: dashboardWrapper
      }, {
        path: 'dashboard',
        component: commentsWrapper
      }
    ]
}

나는 이미 여기서 이것에 대해 대답했다.

다음은 소품을 경로 구성요소에 전달할 수 있는 몇 가지 방법.

리액트러터 v5로 구성요소로 포장해 경로를 만들 수 있어 이렇게 원하는 구성요소에 소품을 쉽게 전달할 수 있다.

<Route path="/">
    <Home name="Sai" />
</Route>

마찬가지로 v5의 어린이 소품도 사용할 수 있다.

<Route path="/" children={ <Home name="Sai" />} />

리액터-라우터 v4를 사용하는 경우 렌더 프로펠러를 사용하여 전달하십시오.

사이드 노트 - Ract router children-func 문서에서 인용

때때로 경로가 위치와 일치하는지 여부를 렌더링해야 한다.이런 경우 자녀들이 지원하는 기능을 이용할 수 있다.성냥이 있는지 없는지를 불린다는 것만 빼면 렌더와 똑같이 작동한다.

<Route path="/" render={() => <Home name="Sai" />} />

(https://reactgo.com/react-router-pass-props/)에 게시됨.

반응 라우터 2.x의 경우.

const WrappedComponent = (Container, propsToPass, { children }) => <Container {...propsToPass}>{children}</Container>;

그리고 당신의 경로로...

<Route path="/" component={WrappedComponent.bind(null, LayoutContainer, { someProp })}>
</Route>

세 번째 매개 변수가 다음과 같은 개체인지 확인하십시오.{ checked: false }.

반응 라우터의 문제는 그것이 당신의 구성요소를 렌더링하여 소품에서 당신이 패스하는 것을 멈추게 한다는 것이다.반면에 네비게이션 라우터는 당신이 당신 자신의 구성요소를 렌더링할 수 있게 해준다.그것은 당신이 다음의 코드와 JsFiddle 쇼와 함께 소품들을 통과하기 위해 어떤 후프들을 뛰어넘을 필요가 없다는 것을 의미한다.

var Comments = ({myProp}) => <div>{myProp}</div>;

var stateNavigator = new Navigation.StateNavigator([
  {key:'comments', route:''}
]);

stateNavigator.states.comments.navigated = function(data) {
  ReactDOM.render(
    <Comments myProp="value" />,
    document.getElementById('content')
  );
}

stateNavigator.start();

Rajesh Naroth 답변을 기반으로 라우터가 있거나 없는 구성 요소를 사용하십시오.

class Index extends React.Component {

  constructor(props) {
    super(props);
  }
  render() {
    const foo = (this.props.route) ? this.props.route.foo : this.props.foo;
    return (
      <h1>
        Index - {foo}
      </h1>
    );
  }
}

var routes = (
  <Route path="/" foo="bar" component={Index}/>
);

아니면 이런 식으로 할 수도 있다.

export const Index = ({foo, route}) => {
  const content = (foo) ? foo : (route) ? route.foo : 'No content found!';
  return <h1>{content}</h1>
};

Ract Router v5.1(React >= 16.8) 방법:

<Route path="/comments">
    <Comments myprop="value" />
</Route>

이제 구성 요소 내의 Route Props에 액세스하려면 이 솔루션을 참조하십시오.기능부품의 경우, 그 포스트에 언급되지 않은 또 다른 후크가 있다.

추가 참조:라우터 v5.1 반응

반응 측정 2.5.2의 경우 해결책은 매우 쉽다.

    //someConponent
...
render:function(){
  return (
    <h1>This is the parent component who pass the prop to this.props.children</h1>
    {this.props.children && React.cloneElement(this.props.children,{myProp:'value'})}
  )
}
...

사용자 지정 경로 구성 요소를 사용하면 라우터 v3 반응에서 이 작업을 수행할 수 있다.

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var routes = (
  <Route path="/" handler={Index}>
    <MyRoute myprop="value" path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

에 대해서는<MyRoute>컴포넌트 코드는 다음과 같아야 한다.

import React from 'react';
import { Route } from 'react-router';
import { createRoutesFromReactChildren } from 'react-router/lib//RouteUtils';

const MyRoute = () => <div>&lt;MyRoute&gt; elements are for configuration only and should not be rendered</div>;

MyRoute.createRouteFromReactElement = (element, parentRoute) => {
    const { path, myprop } = element.props;
    // dynamically add crud route
    const myRoute = createRoutesFromReactChildren(
        <Route path={path} />,
        parentRoute
    )[0];
    // higher-order component to pass myprop as resource to components
    myRoute.component = ({ children }) => (
        <div>
            {React.Children.map(children, child => React.cloneElement(child, { myprop }))}
        </div>
    );
    return myRoute;
};

export default MyRoute;

사용자 지정 경로 구성요소 접근법에 대한 자세한 내용은 http://marmelab.com/blog/2016/09/20/custom-react-router-component.html이라는 제목의 블로그 게시물을 참조하십시오.

이것은 아마도 쿠키 핸들러와 반응-도메인을 사용하는 가장 좋은 방법일 것이다.

색인 js로

import React, { Component } from 'react'
import {Switch,Route,Redirect} from "react-router-dom"
import {RouteWithLayout} from "./cookieCheck"

import Login from "../app/pages/login"
import DummyLayout from "../app/layouts/dummy"
import DummyPage from "../app/pages/dummy" 

export default ({props})=>{
return(
    <Switch>
        <Route path="/login" component={Login} />
        <RouteWithLayout path="/dummy" layout={DummyLayout} component={DummyPage} 
        {...props}/>
        <Redirect from="/*" to="/login" />
    </Switch>
  )
}

그리고 쿠키체크를 사용한다.

import React , {createElement} from 'react'
import {Route,Redirect} from "react-router-dom"
import {COOKIE,getCookie} from "../services/"

export const RouteWithLayout = ({layout,component,...rest})=>{
    if(getCookie(COOKIE)==null)return <Redirect to="/login"/>
        return (
        <Route {...rest} render={(props) =>
            createElement(layout, {...props, ...rest}, createElement(component, 
      {...props, ...rest}))
       }
      />
    )
}
class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      data:null
    }


  }
 componentDidMount(){
   database.ref().on('value', (snapshot) =>{
     this.setState({
       data : snapshot.val()
      })
   });
 }

  render(){
  //  const { data } = this.state
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path = "/" component = { LandingPage }  />
        <Route 
          path='/signup' 
          render = { () => <Signup  data = {this.state.data} />} />
        </Switch>
    </BrowserRouter>

  );
  }
};

export default App;

아래처럼 솔루션을 사용하고 v3.2.5에서 작동하십시오.

<Route
  path="/foo"
  component={() => (
    <Content
      lang="foo"
      meta={{
        description: lang_foo.description
      }}
    />
  )}
/>

또는

<Route path="/foo">
  <Content
    lang="foo"
    meta={{
      description: lang_foo.description
    }}
  />
</Route>

react-router-v3에서는 어떤 해결책도 찾지 못하기 때문에 큰 절충을 하고, 소품대신 class acception을 사용한다.

예를 들면 다음과 같다.

class MyComments extends Comments{
  constructor(props) {
    super(props);
    this.myProp = myValue;
  }
}

그리고, 너는MyComments라우터에component소품 없이

그러면, 당신은 사용할 수 있다.this.myProp'myValue'를 받다componentDidMount()기능;

참조URL: https://stackoverflow.com/questions/27864720/react-router-pass-props-to-handler-component

반응형