バグを説明する
DragSource
装飾されたコンポーネントはまったくレンダリングされません(レンダリング関数は呼び出されません)
再現するには
そのようなコンポーネントを書く:
import * as React from "react";
import styled from "styled-components";
import {
DragSource,
DragSourceConnector,
DragSourceMonitor,
ConnectDragSource
} from "react-dnd";
const ImageHolder = styled.div`
margin: 10px;
max-width: 200px;
width: 200px;
min-height: 100px;
position: relative;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
`;
const ImageNameHolder = styled.div`
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 10px;
background-color: rgba(0, 0, 0, 0.5);
font-size: 13px;
`;
interface Props {
imagePath: string;
connectDragSource?: ConnectDragSource;
isDragging?: boolean;
}
@DragSource<Props>(
"image",
{
beginDrag: (props: Props) => props.imagePath
},
(connect: DragSourceConnector, monitor: DragSourceMonitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
})
)
export class PhotosBrowserPhoto extends React.Component<Props> {
render() {
const { imagePath, connectDragSource } = this.props;
console.log({ connectDragSource });
return connectDragSource(
<div>drag me</div>
);
}
}
予想される行動
drag me
テキスト、 connectDragSource
がコンソールに印刷されたドラッグ可能なコンポーネント
実際の動作
何もレンダリングされず、コンソールは空です
ES6構文を使用していますが、同じことが起こっています。
import React, { Component } from "react";
import { DragSource } from "react-dnd";
import PropTypes from "prop-types";
import "./Dictionary.css";
const propTypes = {
entry: PropTypes.object.isRequired,
// Injected by React DnD:
isDragging: PropTypes.bool.isRequired,
connectDragSource: PropTypes.func.isRequired
};
const TYPES = {
ROW: "row"
};
/**
* Implements the drag source contract.
*/
const rowSource = {
beginDrag(props) {
console.log(props);
return {
entry: props.entry
};
}
};
/**
* Specifies the props to inject into your component.
*/
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
class Row extends Component {
constructor(props) {
console.log("here");
super(props);
this.state = {
entry: props.entry
};
}
static getDerivedStateFromProps = (props, state) => {
return {
entry: props.entry
};
};
render() {
const { isDragging, connectDragSource } = this.props;
const { entry } = this.state;
console.log("dragging:", isDragging);
return connectDragSource(
<div style={{ opacity: isDragging ? 0.5 : 1 }} className="row">
<div>{entry.string}</div>
<div>{entry.kMandarin}</div>
<div>{entry.kDefinition}</div>
</div>
);
}
}
Row.propTypes = propTypes;
export default DragSource(TYPES.ROW, rowSource, collect)(Row);
使用:
"react-dnd-html5-backend": "^5.0.1",
"react-dom": "^16.5.1",
予想:レンダリングされたコンポーネントとコンソールのログを参照してください
実際:何もレンダリングされません。 何も記録されません
アプリのルートにプロバイダーコンポーネントを追加すると、問題が解決しました。
ただし、サンプルコードでは、必要であることを明確に示す必要があると思います。ライブラリの使用を開始する方法を理解するには、例を見るだけで十分だと思いました。
問題はこのif
ステートメントだと思います:
https://github.com/react-dnd/react-dnd/blob/934efc81871f30c6038e2dc52be1504fe38132e7/packages/react-dnd/src/decorateHandler.tsx#L210
コンテキストがない場合にエラーをスローするチェックを無効にしているようです。
以下に示すように、プロバイダーを追加する必要がありました。
import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContextProvider } from "react-dnd";
<DragDropContextProvider backend={HTML5Backend}>
<App/>
</DragDropContextProvider>
fyi:ポータルを使用しているときに問題が発生し、古いReactDOM.unstable_renderSubtreeIntoContainer
APIをReactDOM.createPortal
置き換えることで修正しました。
なぜ私はレンダリングの理由のトラブルシューティングに多くの時間を費やさなかったのですか、ここで答えを見つけました、あなたのサンプルを真剣にやってください、ありがとう
React 16.8.1に対して存在しているようですが、私のマネージャーは作成されず、 DragSource
内のContext.Consumerは子をレンダリングしません。
これは、ドキュメントのクイックスタートセクションのどこにもありません。
これは事実上、ドキュメントにあるべき最初のものです...
ここでも同じ問題がありますが、特定の本番ビルドでのみ発生します( DragDropContextProvider
がツリーに存在することを確認しました)。 反応開発ツールを使用すると、 DragDropContextProvider
が失われ、コンポーネントツリーにUnknown
として表示されることに気付きました(スクリーンショットを参照)
v7.3.2からへのダウングレード
私のためにそれを修正します。
私も同じバグに遭遇しました。
開発中は表示されますが、本番環境では表示されません。
それが私の環境です。
const render = () => {
ReactDOM.render(
<DragDropContextProvider backend={HTML5Backend}>
<Provider store={store}>
<ConnectedRouter history={history}>
<AppContainer>
<App />
</AppContainer>
</ConnectedRouter>
</Provider>
</DragDropContextProvider>,
document.getElementById('app')
);
};
DragDropContextProviderは不明です
この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。
それが自動的に閉じられる前にそれが解決されたかどうか誰かが知っていますか?
私がどのように解決したか
私の場合、開発ではすべて正常に機能しましたが、本番環境では完全に壊れていました。
この問題は、 useDragインポートパスが原因で発生しました...
インポートが機能しないimport {useDrag} from "react-dnd/lib/index";
作業インポートimport {useDrag} from "react-dnd";
そうは言っても、最初のインポートがどのように行われたのかは本当にわかりません。
また、アプリのルートにDndProviderをインポートする必要はないと言っても過言ではありません。 以前にそれを行ったところ、問題の原因はインポートであることがわかりましたが、インポートの「修正」後、アプリルートではなくコンポーネントの1つでDndProviderを復元しました(コードをよりクリーンにするため)。これで問題ありません。大丈夫。
環境:
この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。
まだ解決策はありますか? このトピックで提案されたものは何も役に立ちませんでした。
"react-dnd": "^ 11.1.3"、
"react-dnd-html5-backend": "^ 11.1.3"、
状態の位置を変更した場合にのみすべてが正常に機能します。コンソールログで変更を確認できる間は、レンダリングを確認できません。
最も参考になるコメント
以下に示すように、プロバイダーを追加する必要がありました。