2015-03-01 4 views
4

При рендеринге реагирующего компонента с сервера я вижу ошибку «Не удается найти элемент» после того, как компонент отображает на клиенте.React Unable To Find img Element

Uncaught Error: Invariant Violation: 
findComponentRoot(..., .1ea0t0y2j9c.$img): Unable to find element. 

Если я проверяю источник страницы, я могу увидеть идентификатор компонента, который указан в ошибке.

Вот мои настройки; У меня есть экспресс-сервер с контроллером, который передает компонент в строку и отправляет ее в браузер. Как только браузер отобразит компонент во второй раз, я получаю сообщение об ошибке. Я вижу только эту ошибку для изображений. Я пробовал другие компоненты DOM, но, похоже, они работают нормально. Я уверен, что что-то изменилось во втором рендеринге на клиенте, но я сравнил вывод сервера с выходом клиента, и я не могу найти никаких различий.

Зачем нужен компонент React.DOM.img, чтобы вызвать эту ошибку? Есть ли разница между React.renderToString и React.render, что вызывает разницу в рендеринге тега изображения?

Вот код сервера app.js

'use strict'; 
    var express = require('express'); 
    var React = require('react'); 
    var path = require('path'); 
    var main = React.createElement(require('./main'), {key:'main'}); 


    var app = express(); 
    app.use('/js', express.static(path.join(__dirname, '/js/'))); 
    app.get('/', function(req, res){ 
     var str = React.renderToString(main); 
     res.set('Content-Type', 'text/html'); 
     res.send(str); 
     res.end(); 
    }); 

    var server = require('http').createServer(app); 
    server.listen(9999, function() { 
     console.log('Express server listening'); 
    }); 

Вот код компонента. main.js

Я использую webpack для упаковки сценария main.js.

'use strict'; 
var React = require('react'); 

var Main = React.createClass({displayName: 'Main', 
    render: function(){ 
     return React.createElement('div',null, 
      React.createElement('script',{src: "/js/main.js"}), 
      React.createElement('img',{src: "https://www.google.com/images/nav_logo195.png"})); 
    } 
}); 

if (typeof window !== "undefined") { 
    React.render(React.createElement(Main, {key:'main'}), document.body); 
} else { 
    module.exports = Main; 
} 

Edit: обновлены с учетом предложений @ ssorallen в

+0

Почему вы передаете атрибуты 'key' для каждого элемента? Попробуйте удалить их. –

+0

Просто попытался удалить все ключи, но это не помогло. Спасибо за предложение. – Nael

+0

Какая версия Реагента вы используете? У вас смешанный синтаксис в вашем примере. 'React.DOM.x' устарел и должен быть заменен на' React.createElement ('x', ...) '. –

ответ

1

После некоторого копания в источник среагировать, я узнал, почему IMG тег получаю эту ошибку при первой визуализации страницы.

img, form и input компоненты делают вызов getDOMnode() в componentDidMount случае. Поскольку страница не отображается с сервера, тег img не находится в кеше и не может быть найден при выполнении скрипта.

Решение состоит в том, чтобы поместить созданный сервером скрипт после тега img, чтобы дать браузеру возможность визуализации в первый раз.

Это своего рода хакерское решение, и мне интересно, если это недоразумение с моей стороны или если это только то, как работает рендеринг на стороне сервера для этих тегов.

+0

У меня была такая же проблема с тегом скрипта для некоторых других активов. Это было решением моей проблемы. Перемещение связанного скрипта на последний элемент перед закрытием элемента тела фиксирует вещи. Сообщение об ошибке перед передачей: Ошибка при сбое: невозможно найти элемент с идентификатором 83. – Designer023