Реагируйте: родительский компонент поддерживает дочерний процесс без явного прохождения - PullRequest
0 голосов
/ 22 сентября 2018

Возможно ли, чтобы реквизиты родительского компонента были доступны в дочернем компоненте, не передавая их вниз.

Я пытаюсь реализовать шаблон провайдера, чтобы получить доступ ко всем реквизитам провайдера в егодочерние компоненты.Пример:

Предположим, что приведенный ниже провайдерский комп FetchProvider будет извлекать данные и реквизиты темы самостоятельно, а когда к ним подключен любой дочерний компонент, я хочу получить доступ к обоим реквизитам "data" и "theme" вдочерний компонент также.Как мы можем достичь этого?

class FetchProvider 
{

   proptypes= {
     data: PropTypes.shape({}),
     theme: PropTypes.shape({})
   }

   render()
   {
     // do some
   }

   mapStateToProps()
   {
      return {data, theme};
   }
}

class ChildComponent
{

   proptypes= {
     name: PropTypes.shape({})
   }

   render()
   {
     const{data, them} = this.props; // is this possible here?
     // do some
   }
}

и если я попытаюсь использовать компоненты, указанные выше.

<FetchProvider>
   <ChildComponent name="some value"/>  //how can we access parent component props here? without passing them down
<FetchProvider/>

Ответы [ 4 ]

0 голосов
/ 22 сентября 2018

Ваш вариант использования может быть решен с использованием React context .С помощью Context любой дочерний элемент, завернутый в предоставленный файл, может быть потребителем данных, предоставленных поставщиком.

В вашем случае вы можете использовать его как

context.js

export const FetchContext = React.createContext();

Provider.js

import { FetchContext } from 'path/to/context.js';
class FetchProvider extends React.Component
{

   proptypes= {
     data: PropTypes.shape({}),
     theme: PropTypes.shape({})
   }

   render()
   {
        const { data, theme, children } = this.props;
        return (
             <FetchContext.Provider value={{ data, theme}}>
                   {children}
             </FetchContext.Provider>
        )
   }

   mapStateToProps()
   {
      return {data, theme};
   }
}

ChildComponent.js

class ChildComponent extends React.Component
{

   proptypes= {
     name: PropTypes.shape({})
   }

   render()
   {
     const{data, them} = this.props; // use it from props here
     // do some
   }
}

export default (props) => (
     <FetchContext.Consumer>
           {({ data, theme }) => <ChildComponent {...props} data={data} theme={theme} />}
     </FetchContext.Consumer>
)

Однако, учитывая тот факт, что вы уже используете Redux, который построен наВ контексте контекста вы также можете использовать избыточность и получить доступ к значениям в дочернем компоненте, поскольку они представляют собой те же значения, которые передаются из хранилища Redux дочернему элементу родительским элементом.

class ChildComponent extends React.Component
{

   proptypes= {
     name: PropTypes.shape({})
   }

   render()
   {
     const{data, them} = this.props; // use it from props here
     // do some
   }
}

const mapStateToProps = (state) => {
     return {
          data: state.data,
          theme: state.theme
     }
}
0 голосов
/ 22 сентября 2018

Вы ищете:

class MyParent extends Component {
    render() {
        return <MyChild {...this.props}>
            // child components
        </MyChild>
    }
}

При этом все реквизиты, переданные в MyParent, будут переданы в MyChild.

0 голосов
/ 22 сентября 2018

Это именно то, о чем реагирует контекст .

A Consumer может получить доступ к данным, которые предоставляет Provider, независимо от того, насколько глубоко они вложены.

// Context lets us pass a value deep into the component tree
// without explicitly threading it through every component.
// Create a context for the current theme (with "light" as the default).
const ThemeContext = React.createContext('light');

class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.
    // Any component can read it, no matter how deep it is.
    // In this example, we're passing "dark" as the current value.
    return (
      <ThemeContext.Provider value="dark">

<Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton(props) {
  // Use a Consumer to read the current theme context.
  // React will find the closest theme Provider above and use its value.
  // In this example, the current theme is "dark".
  return (
    <ThemeContext.Consumer>

{theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
  );
}

Вот небольшой рабочий пример :

Примечание Это контекстный API реагирования v16.

0 голосов
/ 22 сентября 2018

Вы можете использовать React.Children для перебора дочерних элементов и передачи любых реквизитов, которые вы хотите отправить, новым клонированным элементам, используя React.cloneElement.

EX:

class Parent extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { children } = this.props;
    const newChildren = React.Children.map(children, child =>
      React.cloneElement(child, { myProp: 'test' }));

    return(
      <View>
        {newChildren}
      </View>
    )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...