У меня есть определенный сценарий в моем универсальном проекте response/redux/express (на стороне сервера).Redux/React - Почему я не могу связать состояние с this.props на компоненте, который находится в iframe?
(1) Во-первых я определил мои маршруты, как так: [routes.jsx]
export default (
<Route component={App} path="/">
<Route component={MainView} path="main">
<IndexRoute component={ThemeIndex}></IndexRoute>
</Route>
<Route component={AnotherView} path="preview" />
</Route>
);
Как вы видите, когда URL маршрута: локальный: 3000/предварительный, реагировать-маршрутизатор будет использовать AnotherView компонент.
(2) В настоящее время сосредоточены на ThemeIndex компонента: [ThemeIndex.jsx]
export default class ThemeIndex extends Component {
render() {
return (
<div>
<h2>Index</h2>
<Frame />
<Control />
</div>
);
}
}
(3) компонент кадров следующим образом: [Frame.jsx]
class Frame extends Component {
render() {
const { text, uid } = this.props.infos;
const themeUrl = `http://localhost:3000/preview?id=${uid}`;
//console.log('Frame theme:', text);
//console.log('Frame uid:', uid);
return (
<div className="col-md-8 panel panel-default">
<div className="embed-responsive embed-responsive-16by9 panel-body">
<iframe src={themeUrl}></iframe>
</div>
<div className="details" >
{text}
</div>
</div>
);
}
}
export default connect(
(state) => {
return {
infos: state.infos
}
}
)(Frame);
Здесь я использую IFrame тег , его src is http://localhost:3000/preview?id=xxxx, так что это означает, что он свяжет AnotherView компонент, который будет страницей iframe.
(4) AnotherView компонент следующим образом:
class AnotherView extends Component {
render() {
const { text, uid } = this.props.infos;
//console.log('AnotherView theme:', text);
//console.log('AnotherView uid:', uid);
return (
<div>
<div >Another View</div>
<div>
{text}
</div>
<div>{uid}</div>
</div>
);
}
}
export default connect(
(state) => {
console.log('another view trigger state:', state);
return {
infos: state.infos
}
}
)(AnotherView);
(4) И у меня есть компонент управления для создания динамического значения: [Component.jsx]
class Control extends Component {
render(){
var uid =() => Math.random().toString(34).slice(2);
return (
<input
onChange={(event) => this.props.addTodo({text:event.target.value, uid:uid()})
/>
)
}
}
export default connect(
(state) => {
return {
infos: state.infos
}
}
)(Control);
(5) Список дополнительных файлов , действий и Разбавление: [action.js]
export function addTodo (attrs) {
return {
type: 'ADD_TODO',
attrs
};
}
[reducer.js]
export default (state = {text:'', uid:''}, action) => {
switch(action.type) {
case 'ADD_TODO':
return Object.assign({}, state, action.attrs);
default:
return state;
}
}
Вот Конфигурационный на server.js:
app.use((req, res) => {
console.log('server - reducers:', reducers);
const location = createLocation(req.url);
const reducer = combineReducers({infos: infosReducer});
const store = applyMiddleware(promiseMiddleware)(createStore)(reducer);
match({ routes, location }, (err, redirectLocation, renderProps) => {
.......
function renderView() {
const createElement = (Component, props) => (
<Component
{...props}
radiumConfig={{ userAgent: req.headers['user-agent'] }}
/>
);
const InitialView = (
<Provider store={store}>
<RoutingContext
{...renderProps}
createElement={createElement} />
</Provider>
);
const componentHTML = renderToString(InitialView);
const initialState = store.getState();
......
мое состояние приложения, как:
{
infos:{
text: '',
uid: ''
}
}
(6) Теперь я ключа некоторые слова на входе в компонент управления. Когда вход onChange вызовет addTodo Функция действия для отправки действия в редукторе, наконец, измените состояние. В общем случае изменение состояния будет влиять на компонент Frame и компонент AnotherView, потому что я использовал react-reduxconnect
, привяжите свойство состояния к компоненту this.props
.
Но на самом деле есть проблема в AnotherView Компонент. в Кадр компонент, console.log
Значение отображает введенный вами текст правильно.В компоненте AnotherView, даже подключения обратного вызова будет триггер (console.log
напечатает another view trigger state: ...
'), в console.log
рендер undefined
, как:
console.log('AnotherView theme:', text); //return AnotherView theme: undefined
console.log('AnotherView uid:', uid); //return AnotherView uid: undefined
Я нашел главную причину: AnotherView компонент находится в iframe
. Потому что, если я удалить iframe
, положить компонент AnotherView прямо здесь, вот так:
return (
<div className="col-md-8 panel panel-default">
<div className="embed-responsive embed-responsive-16by9 panel-body">
<AnotherView/>
</div>
<div className="details" >
{text}
</div>
</div>
);
, то я могу связать state
свойства на this.props
в AnotherView компонент успешно, а затем вставьте {text}
на JSX HTML, вы можете увидеть изменения значения в реальном времени, когда вы вводите значение ввода на Управление Компонент. если я использую iframe для ссылки AnotherView Компонент будет его страницей, вы не видите никакого значения изменения {text}
, потому что мое текстовое значение по умолчанию - пустое строковое значение.
Как связать state
свойствам this.props
в компоненте, который находится в iframe
, когда состояние меняется?
Update Я не могу получить последнюю state
в IFRAME (источник Реагировать компонент), когда я меняя state
в другом компоненте, а на самом деле mapStateToProps
сработал! (Означает источник IFrame компонент), но его состояние не последняя в mapStateToProps
функция. это действительно не касается библиотеки react-redux
?
Это последнее состояние должно быть в компоненте:
Ниже IFrame источник компонент, он не может получить последнее состояние:
Спасибо вашему ответу, вдохновите меня найти другой способ достичь моего объекта. Я должен отображать в iframe, потому что я хотел бы использовать JSX для создания шаблона для рендеринга шаблона в iframe, я не хочу использовать другой механизм шаблонов, например, jade, handleBar ... и т. Д. Если я хотел бы синхронизировать данные о состоянии iframe, возможно ли передать последнее состояние в iframe для связи? –
Я не понимаю, что JSX имеет отношение к iframes. :-( –
Если вы используете что-то вроде 'response-frame-component', вам нужно будет удалить'