我想在组件TextItem(在appview.jsx中)中显示pdf文件中的文本,并且我认为只要状态改变,组件都将重新呈现。但是该组件不会显示新文本,从控制台我知道状态已更改。我允许什么错误?如何获得程序的预期行为?
appview.jsx
import React from 'react';
import { connect } from 'react-redux';
var PDFJS = require('pdfjs-dist');
import { default as InputFile } from './components/inputfile.jsx';
import { default as FileList } from './components/filelist.jsx';
import { writeCurrentFile, showPDF } from "./actions.jsx";
import '../css/styles.scss';
PDFJS.GlobalWorkerOptions.workerSrc =
'../build/webpack/pdf.worker.bundle.js';
class TextItem extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{this.props.text} //I have problem here.
</div>
)
}
}
class AppView extends React.Component {
constructor(props) {
super(props);
}
uploadFileHandler = e => {
const file = e.target.files[0]
if(file !== this.props.currentFile) {
this.props.writeCurrentFile(file);
this.props.showPDF(file, this._pageContainer, this.props.pages);
console.log("Text: ", this.props.text);
}
}
render() {
return (
<div>
<div className="Sidebar">
<div className="ButtonField">
<InputFile uploadFileHandler={this.uploadFileHandler.bind(this)}>
Select a PDF file
</InputFile>
</div>
<FileList currentFile={this.props.currentFile}/>
</div>
<div className="center">
<div className="Content">
<h2 style={{ marginTop: 0, color: "#efefef" }}>
Your PDF file will be viewed here.
</h2>
<div ref={c => this._pageContainer = c}></div>
</div>
<div className="TextField">
<TextItem text={this.props.text} />
</div>
</div>
</div>)
}
};
function mapStateToProps(state) {
return {
text: state.get("text"),
pages: state.get("pages"),
currentFile: state.get("currentFile")
};
}
function mapDispatchToProps(dispatch) {
return {
writeCurrentFile: file => dispatch(writeCurrentFile(file)),
showPDF: (file, _pageContainer, pages) => dispatch(showPDF(file, _pageContainer, pages))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AppView);
actions.jsx
var PDFJS = require('pdfjs-dist');
export function writeCurrentFile(file) {
return {
type: "WRITE_CURRENT_FILE",
file
}
}
export function showPDF(file, _pageContainer, propsPages) {
let fileReader = new FileReader();
let pages = propsPages;
let newPages = [];
let textPages = [];
console.log("First from showPDF!");
fileReader.onload = e => {
PDFJS.getDocument(new Uint8Array(e.target.result)).then(pdf => {
let scale = 2.0;
let viewport, canvas, context, renderContext;
const pageContainer = _pageContainer;
pages.map( page => pageContainer.removeChild(page) )
for (let i = 1; i <= pdf.numPages; i++) {
pdf.getPage(i).then(page => {
viewport = page.getViewport(scale);
// Prepare canvas using PDF page dimensions.
canvas = document.createElement("canvas");
context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.getTextContent().then(text => {
console.log("Begining getTextContent");
var txt = text.items.map(s => s.str).join(' ');
console.log("From getTextContent: ", txt);
textPages.push(txt);
});
// Render PDF page into canvas context.
renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
pageContainer.appendChild(canvas)
newPages.push(canvas)
});
}
});
}
fileReader.readAsArrayBuffer(file);
return {
type: "SHOW_PDF",
newPages,
textPages
}
}
reducer.jsx
import { Map } from "immutable";
var reducer = function(state = Map(), action) {
switch (action.type) {
case "SET_STATE":
return state.merge(action.state);
case "WRITE_CURRENT_FILE":
return state.set("currentFile", action.file);
case "SHOW_PDF":
state = state.set("pages", action.newPages);
return state.set("text", action.textPages);
}
return state;
}
export default reducer;
app.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from "./reducer.jsx";
import AppView from "./appview.jsx";
const store = createStore(
reducer,
applyMiddleware(thunk)
);
store.dispatch({
type: "SET_STATE",
state: {
text: [],
pages: [],
currentFile: null
}
});
ReactDOM.render(
<Provider store={store}>
<AppView />
</Provider>,
document.getElementById("app")
);
谢谢你们的回答:)。